Modifications made to one Array are causing an impact on another Array within the Angular project

In the process of developing an Angular project, I am retrieving API data and displaying it to the user. The project consists of two main components, "Navigation" and "NewsBlock", along with a service named "newsFetchService". The API data is fetched by the newsFetch service and utilized 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); */
  }

}

Currently, when a user clicks on a field in the Navigation component, it triggers an update to the newsBlockData array in Newsfetchservice. This updated newsBlockData is then used by the "newsBlock" component to correctly reflect the data changes. However, there is an issue where modifying the data within the newsBlockData array also impacts the allnews array data. Any additions or deletions in the newsBlockData array are mirrored in the allnews array, even though they are intended to be separate arrays.

I have experimented with different approaches, such as utilizing subscribers and promises, as well as attempting deep and shallow copying, but the issue persists.

Answer №1

The issue lies within the getNews() function. Even though you set both variables to reference separate arrays:

newsBlockData : NewsData[] = [];
allNews : NewsData[] = [];

In the getNews() function, you assign them to point to the same array:

getNews() {
  return new Promise((resolve, reject) => {
    this.http.get<NewsData[]>(this.newsFetchURL).subscribe(res => {
      this.allNews = res;
      this.newsBlockData = res;
      resolve(true);
    })
  })
}

In this scenario, a shallow copy would suffice:

getNews() {
  return new Promise((resolve, reject) => {
    this.http.get<NewsData[]>(this.newsFetchURL).subscribe(res => {
      this.allNews = [...res];
      this.newsBlockData = [...res];
      resolve(true);
    })
  })
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

"Creating a cohesive design: Using CSS to ensure the navigation background complements

I am working on a project with a horizontal navbar that I want to stay fixed while scrolling. The main window has different colored divs as you scroll down, and I would like the navbar to match the image of the main div while scrolling, creating a looping ...

app-root component is not populating properly

As a newcomer to Angular 2, I have embarked on a small project with the following files: app.module.ts import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { MaterialModule } fro ...

When utilizing the ::first-letter pseudo-element on <sub> and <sup> tags

Why is the <sub> and <sup> not supporting the ::first-letter CSS pseudo-element? Any solutions? p:first-letter, sub:first-letter, sup:first-letter { color: red; font-weight: bold; } <p>This text contains <sub>subscript</su ...

Obtaining HTML data with ajax within a WordPress post

Greetings! I've been putting together a website and I'm eager to include a unique timeline in each of my posts. I'm utilizing WordPress for this project. However, since the timeline I want to insert will vary from post to post, I am unable t ...

Using masonry-layout with Next Js leads to a ReferenceError stating that window is not defined

Implementing the masonry-layout library by David Desandro in my Next app has been a smooth process. You can find the link here. When I apply it, the masonry layout functions perfectly as intended. Here's how I'm incorporating it successfully: imp ...

Tests with Protractor are guaranteed to pass as long as the specification is within a loop

ISSUE : While using the code provided in the EXAMPLE section, the expect block inside the forEach loop always passes, which is not the expected behavior. For instance, here is a scenario along with a screenshot of the test report: expect('bt bt-p ...

"JQuery event handlers not functioning as expected: .click and .on failing

For some time now, I've been facing this issue and I'm at a loss trying to figure it out. I have attempted various solutions such as using .click(), .on(), .delegate, and even utilizing .find() to locate the specific element causing the problem. ...

Encountered an issue with `ng serve` following the execution of `ng update @angular/cli @angular/core` resulting in the inability to serve the

I encountered some issues in my Angular project when trying to build a docker image. To resolve the error, I utilized ng update @angular/cli @angular/core successfully, allowing me to now create a docker container for my project. However, I am facing a new ...

JavaScript plugin designed for effortless conversion of JSON data to structured HTML code

I want to add this JSON data to an HTML element. [ { "website":"google", "link":"http://google.com" }, { "website":"facebook", "link":"http://fb.com" } ] Is there an easy way to convert this using a plugin ...

If I deselect an item, the "check all" option does not become deselected

I recently designed a page that displays all the weekdays and dates from Monday to Sunday. I added a feature where users can check all the weekdays with a single click, and uncheck them with another click. However, I encountered an issue where unchecking a ...

working with json files in node.js

I have encountered an issue with manipulating a JSON file using Node.js. Here is the scenario: { "joe": { "name": "joe", "lastName": "black" }, "matt": { "name": "matt", "lastName": "damon" } } Now, I n ...

Looking to add a dropdown feature to my current main navigation bar

I've been struggling to add a drop-down menu to my website's main menu. Every time I try, something goes wrong - sometimes the menu appears inline, other times it completely messes up the layout. Here is the HTML code snippet: <ul class="m ...

Error: The URL provided to the AngularJS factory is not properly formatted

I am facing an issue with passing a URL from a controller to a factory in my service. I have multiple URLs and want to dynamically pass any URL. var youtubeURL = 'https://www.googleapis.com/youtube/v3/videos?part=snippet'; ConnectivityS ...

Is there a way in JavaScript to launch a link in a new tab and overlay a div on top of the existing content of the page?

Is there any method in JavaScript to open a link in a new tab and add a div element on that page? Let's say I have a page called page1.html which has a div containing a link and two radio buttons "yes" and "no". I want to open the link in a separate t ...

Exploring methods for obtaining client origin in Vue

I have a variety of domains such as https://www.ilajobs.com and levelcoding.com When attempting to retrieve the client's origin using the following code: getOrigin() { this.origin = window.location.origin; }, The expected result should be: ilajob ...

Only line breaks are permitted in Mustache.js, all other HTML characters are escaped

After a user submits input, I am generating comments and displaying them using Mustache.js. When it comes to rendering the comments, I have found that replacing user-entered line breaks (\n) with <br/> allows them to display as HTML breaks. To ...

How can I obtain an array using onClick action?

Can anyone help me figure out why my array onClick results are always undefined? Please let me know if the explanation is unclear and I will make necessary adjustments. Thank you! Here is the code snippet: const chartType = ["Line", "Bar", "Pie", " ...

Something seems off with the color of the getImageData when using Fabric JS getContext('2d')

Website: Currently, I am working on adding an eye dropper feature to my website. It functions perfectly at a resolution of 1080p, but when tested on higher or lower resolutions, it malfunctions. Here is the basic code snippet: var ctx = canvas.getContex ...

The Angular 11 library module has been successfully imported into the consuming app but it is not being utilized

Currently, I am in the process of creating an Angular library that will encompass services, pipes, and directives to be utilized across various Angular projects within my organization. At this point, I have successfully implemented three services within th ...

Automatic Textbox Closer

Connected to this AngularJS issue on IE10+ where textarea with placeholder causes "Invalid argument." and also this AngularJS 1.1.5 problem in Internet Explorer with ng-show and objects (Bug), we had to resort to using the textarea element as a self-closin ...