How this code move from Category to another?

I am trying an example for chain of responsibility but I dont fully understand the code. Here is the small json I use

{
    "design": [
        {"name": "Photoshop", "price": 5},
        {"name": "After Effect", "price": 15},
        {"name": "Sketch", "price": 10}
    ],
    "language": [
        {"name": "English", "price": 53},
        {"name": "French", "price": 54},
        {"name": "German", "price": 60}
    ],
    "music": [
        {"name": "F1 Studio", "price": 71},
        {"name": "Adobe Audition", "price": 42},
        {"name": "DJ", "price": 47}
    ]
}

And here is the code:

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 ?

setNext sets the .next property of the category, which the search command uses to move to the next category.

no, after your search within that category is when the next parameter is used. It has to be set before that.

1 Like

Still confused. In these lines:

design.setNext(language);
language.setNext(music);

From what I see this mean now this.next point to latest category music so it will only search this category :thinking:

Ah, you’ve been confused by this.

this refers to the current instance of the object.

Give this a read, see if it helps clear things up:

no in the 2 lines above I read them like this:

design.setNext(language);

Will make this.next = language then

language.setNext(music);

Will make this.next = music

so this.next.search(itemName); will search in Music category only ?

except this changes each time.

design.setNext(language);
this = design

language.setNext(music);
this = language

1 Like

I can not understand I tried to debug the code step by step. How this change to different categories ?

Try this set of pages instead. Not… strictly using the class definition, but its OOP basics.

1 Like

Thanks I read it but still dont understand how this.next.search change the value of this in the code above :pensive:

Well, the setNext method is responsible for that.

    setNext(categoryName){
        this.next = categoryName;
    }

    ...

        design.setNext(language);
        language.setNext(music);
1 Like

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

After this search?

    find(itemName) {
        return this.category.search(itemName);
    }

No while I debug in visual studio code I find this chnage after this line search !!!

return this.next.search(itemName);

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);

And, here is a sample of the running code: https://jsfiddle.net/pmw57/gLw057j2/

1 Like

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 :frowning:

Appreciate your help and hope you always be around here. :bouquet:

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.