Editing a method with an array of objects

Viewed 54

I have a method that contains an array of objects, and I would like to be able to edit the desiredMin and desiredMax values.

    watchedRivers(): RiverInfo[] {
    return [
      {
        name: 'Sample River 1',
        address: 'Optional Address 1',
        currentFlow: 2.78,
        desiredMin: 1.5,
        desiredMax: 6
      },
      {
        name: 'Sample River 2',
        currentFlow: 857,
        desiredMin: 100,
        desiredMax: 500
      },
      {
        name: 'Sample River 3',
        address: 'Optional Address 1',
        currentFlow: 2800,
        desiredMin: 400,
        desiredMax: 3000
      }
    ];
  }

The method I call to do so is not overwriting the object.

updateFlows(index: number, updatedRiver: RiverInfo) {
    console.log(updatedRiver);
    this.watchedRivers()[index] = updatedRiver;
    console.log(this.watchedRivers()[index]);
    this.watchedRiversChanged.next(this.watchedRivers().slice());
  }

The updatedRiver object looks like the correct format in the console. Why isn't it overwriting?

4 Answers

The best solution is to not mutate this.watchedRivers()

updateFlows(index: number, updatedRiver: RiverInfo) {
  const dataUpdated = [..this.watchedRivers()];
  dataupdated[index] = updatedRiver;
  this.watchedRiversChanged.next(dataUpdated);
}

Every time when you call the watchedRivers() method, it returns a new array of RiverInfo objects containing Sample River 1, Sample River 2 and Sample River 3. So assigning the updatedRiver object to watchedRivers()[index] would not modify the RiverInfo object inside the method.

If you want to persist the updatedRiver info, you can do it in either of the two ways as shown below:

  1. Instead of returning the array from a method, you can store it in a class-level variable.
class SomeClass {
  // Storing the values in a class level variable
  // so that it is accessible in all methods of this class
  private watchedRivers: RiverInfo[] = [
    {
      name: "Sample River 1",
      address: "Optional Address 1",
      currentFlow: 2.78,
      desiredMin: 1.5,
      desiredMax: 6
    },
    {
      name: "Sample River 2",
      currentFlow: 857,
      desiredMin: 100,
      desiredMax: 500
    },
    {
      name: "Sample River 3",
      address: "Optional Address 1",
      currentFlow: 2800,
      desiredMin: 400,
      desiredMax: 3000
    }
  ];

  updateFlows(index: number, updatedRiver: RiverInfo) {
    console.log(updatedRiver);
    this.watchedRivers[index] = updatedRiver;
    console.log(this.watchedRivers[index]);
    this.watchedRiversChanged.next(this.watchedRivers.slice());
  }
}

Now updates are persisted in the class-level variable.

  1. If you do not want to modify the method, you can store the array in a local variable and then perform your logic.
updateFlows(index: number, updatedRiver: RiverInfo) {
    console.log(updatedRiver);
    let localData = this.watchedRivers();
    localData[index] = updatedRiver;
    console.log(localData[index]);
    this.watchedRiversChanged.next(localData.slice());
}

You are doing it wrong way

1) In function watchedRivers you are just returning a new array of objects. So Every time when you call this function it will return fresh array without any change

2) Set RiverInfo[] in component property (variable) separately

   data: RiverInfo[] = [
    {
      name: "Sample River 1",
      address: "Optional Address 1",
      currentFlow: 2.78,
      desiredMin: 1.5,
      desiredMax: 6
    },
    {
      name: "Sample River 2",
      currentFlow: 857,
      desiredMin: 100,
      desiredMax: 500
    },
    {
      name: "Sample River 3",
      address: "Optional Address 1",
      currentFlow: 2800,
      desiredMin: 400,
      desiredMax: 3000
    }
  ];

3) Than from your function return that data from your function

     watchedRivers(): RiverInfo[] {
            return this.data;
     }

4) Try this

https://stackblitz.com/edit/angular-wwwpon?embed=1&file=src/app/app.component.ts

The reason why you are getting the above issue is the scope of RiverInfo Array is limited to function and the RiverInfo Array is garbage collected as soon as the function execution completes.

Related