1

I have somewhat similar problem like one here angular component one-time binding from $http shows undefined.

I've got async call in parent component:

this.SomeApi.getSomeData(params, (data) => {
    this.someDataList = data;
    console.log('getSomeData this.someDataList:', this.someDataList);
});

which uses $http:

getSomeData(params) {
    return this.$http.post(this.url + 'data_source/getSomeDataList', params)
    .then((data) => {
        if (data.status === 200) {
          callback(data.data);
          return data.data.someDataList;
        } else {
          return null;
        }
    });
}

console.log('getSomeData this.someDataList:', this.someDataList); returns data from response, so that works fine.

But in child component, which btw. has such binding:

bindings: {
    someBind1: '<',
    someBind2: '=',
    someDataList: '<?'
},

I've got $onChanges hook function:

$onChanges(changesObj) {
  console.log('changesObj:', changesObj);
  if (changesObj.someDataList && changesObj.someDataList.currentValue) {
    this.someDataList = changesObj.someDataList.currentValue;
    console.log('$onChanges this.someDataList:', this.someDataList);
  }
}

First console.log show this:

{
  someBind1: SimpleChange {previousValue: UNINITIALIZED_VALUE, currentValue: {…}}
  someBind2: SimpleChange {previousValue: UNINITIALIZED_VALUE, currentValue: {…}}
  someDataList: SimpleChange {previousValue: UNINITIALIZED_VALUE, currentValue: undefined}
  __proto__: Object
}

second shows this: $onChanges this.someDataList: undefined

that's before the init of this child-component's controller.

But after the $http response is done, the second time $onChanges is invoked, the passed object disappears from changesObj inside hook, so only first console.log from within hook is printed, but second never.

I found somewhere on github info ($onChanges hook isn't working properly when using Promises #16480), that:

The problem you have found is that native Promises do not understand about the AngularJS digest cycle. You need to use the built-in AngularJS promise library $q.

But, the in the official docs for AngularJS $http service there is written, that:

The $http API is based on the deferred/promise APIs exposed by the $q service.[...]

So, my async call code should be theoretically "synced" with digest cycles, and no such problem should appear, right?

Even after modifying code for above posted async call to incorporate $q, still nothing is working as it should:

getSomeData(params) {
    return this.$http.post(this.url + 'data_source/getSomeDataList', params)
        .then((data) => {
            if (data.status === 200) {
                return data.data.someDataList;
            } else {
                return null;
            }
        }
    );
}

this.$q.when(this.SomeApi.getSomeData(params)).then( (data) => {
    this.someDataList = data;
    console.log('getSomeData this.someDataList:', this.someDataList);
});

Above works same as earlier version of code, thus, first console.log right after response is printed, and data is seen, and first console.log from $onChanges hook prints this:

{
  someBind1: SimpleChange {previousValue: UNINITIALIZED_VALUE, currentValue: {…}}
  someBind2: SimpleChange {previousValue: UNINITIALIZED_VALUE, currentValue: {…}}
  __proto__: Object
}

There's no someDataList property at all, so second console.log from hook won't be printed ever.

I don't get it.

JohnDoenym
  • 55
  • 1
  • 7

0 Answers0