I am creating a angular project where i am getting API data which i am displaying to user. It has two components "Navigation" and "NewsBlock" and a service called "newsFetchService". API data is fetched by newsfetch service and used by both components.
NewsFetchService
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { NewsData } from './NewsData';
import { HttpClient,HttpHeaders } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class NewsfetchserviceService {
//Global variable storing All fetch data
newsBlockData : NewsData[] = [];
allNews : NewsData[] = [];
constructor(
private http:HttpClient
) { }
private newsFetchURL = 'api/v1/topics';
getNews() {
return new Promise((resolve, reject) => {
this.http.get<NewsData[]>(this.newsFetchURL).subscribe(res => {
this.allNews = res;
this.newsBlockData = res;
resolve(true);
})
})
}
updateNewsBlock(selectedNews : NewsData){
this.newsBlockData.length = 0;
this.newsBlockData.push(selectedNews);
}
}
navigation.component.ts
import { Component, OnInit } from '@angular/core';
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
import { Observable } from 'rxjs';
import { map, shareReplay } from 'rxjs/operators';
import { NewsfetchserviceService } from '../newsfetchservice.service';
import { NewsData } from '../NewsData';
@Component({
selector: 'app-navigation',
templateUrl: './navigation.component.html',
styleUrls: ['./navigation.component.css']
})
export class NavigationComponent implements OnInit{
sourcesList : NewsData[] = [];
ngOnInit(): void {
this.showAllSources();
}
isHandset$: Observable<boolean> = this.breakpointObserver.observe(Breakpoints.Handset)
.pipe(
map(result => result.matches),
shareReplay()
);
constructor(private breakpointObserver: BreakpointObserver,private newsfetch: NewsfetchserviceService) {}
showAllSources():void {
this.sourcesList = this.newsfetch.allNews;
/* this.newsfetch.getNews().subscribe(news => this.news = news); */
}
updateNewsList(source : NewsData):void{
console.log('option selected');
console.log(source);
this.newsfetch.updateNewsBlock(source);
}
}
newsBlock.component.ts
import { Component, OnInit } from '@angular/core';
import { NewsData } from '../NewsData';
import { NewsfetchserviceService } from '../newsfetchservice.service';
@Component({
selector: 'app-newsblock',
templateUrl: './newsblock.component.html',
styleUrls: ['./newsblock.component.css']
})
export class NewsblockComponent implements OnInit {
constructor(private newsfetch: NewsfetchserviceService) { }
newsBlockData : NewsData[] = [];
ngOnInit(): void {
this.getNews();
}
getNews():void {
this.newsBlockData = this.newsfetch.newsBlockData;
/* this.newsfetch.getNews().subscribe(news => this.news = news); */
}
}
Now, when user click a field in Navigation component it updates the newsBlockData array in Newsfetchservice. This newsBlockData is used by "newsBlock" component which is correctly updating data based on data changed. Issue i am facing is that updating data within newsBlockData array is also affecting allnews array Data. Any data added or removed from newsBlockData array is also reflected in allnews array even though they are two separate arrays.
I have tried changing approach like trying to use subscriber and promise but getting the same issue. Also tried deep copying and shallow copying but getting the same result
this.allNews = res; this.newsBlockData = res;That makes both properties point to the same array.this.allNews = res; this.newsBlockData = res;withthis.allNews = JSON.parse(JSON.stringify(res)); this.newsBlockData = JSON.parse(JSON.stringify(res));I have already tried this approach but then app loading takes too much time. Is it a symptom of this and no other way around it? or my approach to the problem is wrong ?