Reputation: 361
I'm having a strange problem.
In my component CategoryComponent i have a variable in escope that is:
@Input() category: CategoryModel;
When i make a simple post with a service and return a data i change this variable to change so i make a function that do this:
if (category.uploading) {
this.checkMedia(this.category, this.module);
}
Inside my function i make this:
checkMedia(model: any, module: String) {
let counter = 0;
var refreshIntervalId = setInterval(() => {
const service =
model instanceof CategoryModel
? this.categoryService
: this.foodService;
service
.hasMedia(model)
.pipe(
switchMap((hasMedia) => {
if (hasMedia) {
return service.show(model, module);
}
return of(undefined);
}),
catchError((_) => {
clearInterval(refreshIntervalId);
return of(undefined);
})
)
.subscribe(
(newModel) => {
if (newModel) {
if(newModel.hasMedia) {
model.hasMedia = newModel.hasMedia;
model.images = newModel.images;
model.uploading = false;
console.log(model);
console.log(this.category);
clearInterval(refreshIntervalId);
this.cd.detectChanges();
}
}
},
(_) => {
clearInterval(refreshIntervalId);
}
);
counter++;
if (counter == 3) {
if (refreshIntervalId) {
model.uploading = false;
clearInterval(refreshIntervalId);
this.cd.detectChanges();
}
}
}, 8000);
}
Why in this part:
model.hasMedia = newModel.hasMedia;
model.images = newModel.images;
model.uploading = false;
console.log(model);
console.log(this.category);
clearInterval(refreshIntervalId);
this.cd.detectChanges();
My screen change only if i reference this variable directly like, this.category.name = "TESTE";, for example but when i use with the paremeter model:any, it's change the global variable when i see in console.log() but in my front page the state that i want is not changing why?
Upvotes: 2
Views: 142
Reputation: 57223
THE MAIN CONCERN
The bit I don't understand, what are you doing with model? Why are you not using this.model
? I would expect that you would be referencing model in your HTML somewhere and would thus need to update a class member variable this.model = {blah-blah-blah}
. Have you declared a public property model somewhere in your class? Why is it not being updated? In your class you need to declare:
@Input() category: CategoryModel;
model: any;
And then in your code:
this.model = something
And then in your html:
{{ model | json }}
OTHER POTENTIAL ISSUES
What change detection strategy are you using? OnPush or default? You should not use OnPush unless you are confident with it. Its possible that because you are mutating model change detection is not kicking in. You should avoid object mutation. To fix this try adding this line:
model.hasMedia = newModel.hasMedia;
model.images = newModel.images;
model.uploading = false;
model = {...model}; // creates a new object reference which will cause Angular change detection to kick in
OR
import {cloneDeep} from 'lodash-es';
model.hasMedia = newModel.hasMedia;
model.images = newModel.images;
model.uploading = false;
model = cloneDeep(model); // creates a new object reference which will cause Angular change detection to kick in
I find the second approach more readable.
This is mutation (BAD):
model.hasMedia = newModel.hasMedia;
model.images = newModel.images;
model.uploading = false;
This is not mutation (GOOD):
model = {
...model
hasMedia: newModel.hasMedia;
images: newModel.images;
uploading: false;
}
EDIT ... USING RETURN VALUES
this.checkMedia(this.category, this.module).then((cat) => {
this.category = cat;
});
and return a value from checkMedia
checkMedia(model: any, module: String): Promise<any> {
return new Promise((resolve) => {
// your existing code
resolve(model)
})
}
Upvotes: 0