0

I have an object method below that takes an argument of another object 'backend'. It uses a method from the backend object 'fetchClassrooms$()' which returns an observable. The issue I'm having is that when I try and call the function 'buildDOM' from the observable's execution I get the error "cannot read property 'buildDOM' of undefined". I think it's a scoping issue where the observable's execution scope is different from the 'fetchClassrooms' scope. If so, is there a better way of calling a function from within an observable's execution that comes from a different object?

fetchClassrooms (backend) {
    function buildDOM (data) {
        for(let classroom in data){
            for (let student in data[classroom]){
                let time = data[classroom][student];
                this.buildDOM(classroom, student, time);
            }
        }
        this.classroomSelected = Object.keys(data)[0];   
    };

    backend.fetchClassrooms$()
        .subscribe(
            dataSnapshot => {
                this.classrooms = dataSnapshot.val();
                buildDOM(this.classrooms);                       
            },
            err => console.log(err),
            () => console.log('complete')
        );
},
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Brad Woods
  • 1,507
  • 2
  • 12
  • 30
  • 1
    Define `buildDOM` as an arrow function. – Felix Kling Apr 05 '16 at 23:36
  • `this` is bound to `window`, not `fetchClassrooms`, and `window` is outside `fetchClassrooms`. Since `window` can't access items in `fetchClassrooms`'s scope, `buildDom` is undefined to it. – Akshat Mahajan Apr 05 '16 at 23:40
  • I might not have explained it very well but the structure is `myObject{fetchClassrooms(){ ... }}`. I ran a test and 'this' is set to 'myObject', not the window. – Brad Woods Apr 06 '16 at 00:19
  • Felix, changing buildDOM to `var buildDOM = (data) => { ... }` works like a charm. Would you be able to explain why? – Brad Woods Apr 06 '16 at 00:27
  • I don't see how this question is related to 'How to access the correct `this` / context inside a callback?' as that topic is referring to the value of 'this'. My question is related to simply calling a function within a callback. I don't see the correlation but I could be wrong. – Brad Woods Apr 06 '16 at 00:46
  • @BradWoods: There error you were getting comes from the line `this.buildDOM(…)` in the `buildDOM` function, not from the `buildDOM(…)` call in the subscribe callback (which works fine). Btw, the deletion of that line messes up your question imo – Bergi Apr 06 '16 at 00:51
  • Sorry but that is not true. I removed this.buildDOM (it had nothing to do with the issue). The error is coming from simply calling 'buildDOM', which should simply call the function above backend.fetchClassroom$ – Brad Woods Apr 06 '16 at 03:05
  • *"I don't see how this question is related to..."* Calling `buildDOM()` simply makes `this` inside the function refer to `undefined`, hence accessing `this.buildDOM` throws the error "cannot read property 'buildDOM' of undefined". I believe you already know how arrow functions work, otherwise you wouldn't be passing one to `subscribe`. By using an arrow function, `this` refers to the correct object and `this.buildDOM` works. `buildDOM` is essentially a callback, only that you call it explicitly inside another callback. The same rules for solving issues with `this` apply though. – Felix Kling Apr 06 '16 at 05:27

0 Answers0