Modifying local variables in components modifies shared service variable in Angular 2? -
here service:
import { injectable } '@angular/core'; import { headers, http, response } '@angular/http'; import { observable } 'rxjs/rx'; import 'rxjs/observable/of'; import 'rxjs/add/operator/share'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/catch'; @injectable() export class caseservice { private data:any; private observable: observable<any>; constructor(private _http: http) {} public getcase() { const url = 'http://localhost:55130/api/case?caseid=123'; if (this.data) { //after filtering array of objects on local variable //in controller, this.data modified console.log(this.data); return observable.of(this.data); } else if (this.observable) { return this.observable; } else { let headers = new headers(); headers.append('content-type', 'application/json'); this.observable = this._http.get(url,{headers:headers}) .map(response => { this.observable = null; this.data = response.json(); return this.data; }).share(); return this.observable; } } }
in home component, in ngoninit, doing following:
ngoninit() { this._caseservice.getcase().subscribe(data => { this.case = data; //filter this.case.casecontent array //when this, return correct object array //but modifies data variable on shared service //which don't want this.case.casecontent = this.case.casecontent.filter(function(item){ return item.route == '/home'; })[0]; }); }
why when modify local variable in home controller, modifies variable in shared service. trying when go home page, filter out content home page , when access contact page, full object again, cache , filer out content contact page, when go contact page, casecontent object , not array of objects.
you're using same instance of 'data' variable. returning reference type method doesn't clone/copy object, creates new pointer (that points same object in memory).
you can solve removing internal caching:
@injectable() export class caseservice { constructor(private _http: http) {} public getcase() { const url = 'http://localhost:55130/api/case?caseid=123'; let headers = new headers(); headers.append('content-type', 'application/json'); return this._http.get(url,{headers:headers}) .map(response => { return response.json(); }); } }
or if want cache observable , data, should clone object on returning, smth 'return observable.of(deepclone(this.data));'
search in google how deep clone objects in js, or implement custom method.
in case, best cache string json response , call 'json.parse()' on every access.
this.data = response.text(); return json.parse(this.data);
Comments
Post a Comment