Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't my property being updated inside the "Scope"?

I am starting to venture into Angular2 for a hobby project and have run into something I don't know how to debug or search for yet.

I started out using the ng2-play repository.

I have two simple classes (this code is drastically simplified for this post):

words-ui.js

export class WordsUI {
  constructor() {
    new Words(data => this.words = data);
  }
}

words-ui.html

<ol *if="words" reversed>
  <li *for="#entry of words" title="Word for week starting {{entry.date}}">{{entry.word}}</li>
</ol>

words-data.js

export class Words {
  constructor(cb) {
    firebase
      .child('words')
      .on('value', data => cb(data.val()));
  }
}

The only thing that isn't working correctly yet is the "scope" recognizing that the value of the property words has been updated. This means that when the UI loads nothing is shown in the list of words. If I then add a word to the list through the UI all words, plus the added word, show up. Or, if I put in a setTimeout to "reload" the words property with it's own value they show up.

I imagine that I am not using the right pattern for this but where would I find out what pattern would be better for this situation. I am a little lost in the new ES6 module system as well as: TypeScript and AngularJS 2.

I think I have provided the relevant portions of code to illustrate the problem but if not please let me know and I can work on putting together something better.

UPDATE 1: Added view file. The change to words on the "context" of WordsUI instance aren't reflected.

like image 431
kalisjoshua Avatar asked Oct 31 '22 05:10

kalisjoshua


1 Answers

So I found an answer - or work around, depending on your point of view - to this situation a few hours after running into it originally. The final repository for this hobby project is on GitHub Weekly Word.

The Problem

I was essentially attempting to set a property on the WordsUI instance from within the callback passed to the Word constructor. I think somehow that was not being picked up but the "scope watcher" zones.js (I think).

The Resolution

I moved the reading of data, from the Word instance, into a subsequent call from the instance; rather than trying to be tricky and keeping that in the callback passed to the constructor.

I don't think that this approach - the one I ended up using - is inferior necessarily, nor was the former superior really in any way.

words-ui.js

export class WordsUI {
  constructor() {
    this words = new Words();
    this.update();
  }

  update() {
    this.words
        .read(words => {
            this.wordList = words;
        })
  }
}

words-data.js

export class Words {
  constructor() {
    firebase = new Firebase('http://weekly-word.firebase.com').child('words');
  }

  read(cb) {
    firebase
        .on('value', data => {
            cb(data);
        })
  }
}
like image 142
kalisjoshua Avatar answered Nov 10 '22 18:11

kalisjoshua