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.