const courses = require('./courses.json');
class Category {
constructor (name, courses = []){
this.name = name;
this.courses = courses;
this.next = null;
}
setNext(categoryName){
this.next = categoryName;
}
search(itemName){
const index = this.courses.map(item => item.name).indexOf(itemName);
const found = this.courses[index];
if (found) {
return {
name: found.name,
price: found.price,
location: this.name
}
} else if (this.next) {
return this.next.search(itemName);
} else {
return `${itemName} not found`;
}
}
}
class Finder {
constructor(name, courses = []){
this.name = name;
this.courses = courses;
const design = new Category('design', courses.design);
const language = new Category('language', courses.language);
const music = new Category('music', courses.music);
design.setNext(language);
language.setNext(music);
this.category = design;
}
find(itemName) {
return this.category.search(itemName);
}
}
const result = new Finder('my course', courses).find('DJ');
console.log(result);
My problem I dont understand how setNext method work and why it is called in the constructor, as I think it should be after I not find my search I should call setNext ?
this.next.search is calling setNext like set and get ? because when I trace the code I find that after calling search, this value change but I dont understand how
Yes. While in the Finder class the this keyword refers to Finder. When you return out of the Finder class the this keyword no longer refers to Finder.
Because the this keyword commonly leads to confusion, I’ve taken to not using classes and have opted for composition over inheritance.
Here’s the same code without using classes and it looks quite similar.
Instead of using the this keyword though, actual names are used such as category and finder.
Hopefully this might help to dispel some misunderstandings about what the code is doing.
import * as courses from "./courses.json";
function makeCategory(name, courses = []) {
const category = {};
category.name = name;
category.courses = courses;
category.next = null;
category.setNext = function setNext(categoryName) {
category.next = categoryName;
};
category.search = function search(itemName) {
const index = category.courses.map(
(item) => item.name
).indexOf(itemName);
const found = category.courses[index];
if (found) {
return {
name: found.name,
price: found.price,
location: category.name
};
}
if (category.next) {
return category.next.search(itemName);
}
return `${itemName} not found`;
};
return category;
}
function makeFinder(name, courses = []) {
const finder = {};
finder.name = name;
finder.courses = courses;
const design = makeCategory("design", courses.design);
const language = makeCategory("language", courses.language);
const music = makeCategory("music", courses.music);
design.setNext(language);
language.setNext(music);
finder.category = design;
finder.find = function find(itemName) {
return finder.category.search(itemName);
};
return finder;
}
const result = makeFinder("my course", courses).find("DJ");
console.log(result);
Thanks Paul alot. I was confused how design move to language and how language to music but I understand now that the .next property store the next category for each category this was not obvious for me.
I like to use composition like you but when I am in interview and dont know how to use classes , you know the result, rejection
Appreciate your help and hope you always be around here.