anonymous
anonymous

Reputation: 1681

Update value in an array of object every time a button is clicked

I have a button, and an array of object like so,

<button (click)="appendDataToLink()">

test = [
   { name: 'karthik', id: 1, link: '/abc/def/ghi' },
   { name: 'shahbaz', id: 2, link: '/jkl/mno/pqr'}
]

when the button is clicked, I want to add a random text in the link of the test array. like, link: "/abc/def/ghi/rd-5"

but whats happening is link: "/abc/def/ghi/rd-5/rd-7" as you can see here rd-7 is appended to it instead of link: "/abc/def/ghi/rd-7"

Here is the method appendDataToLink() is called every time the button is clicked.

generateRandomNumber() {
   return Math.floor(Math.random() * 10);
}
appendDataToLink() {
  this.test.forEach( e => {
     e.link = `${e.link}/rd-${this.generateRandomNumber()}`
  });
  console.log(this.test);
}

Please find my code on stackblitz

Upvotes: 0

Views: 1174

Answers (5)

Carlos S&#225;
Carlos S&#225;

Reputation: 622

Like I linked in my comment, this is a simple way to do it https://stackblitz.com/edit/angular-5bq8ez?file=src/app/app.component.ts You save the original link and use it to generate future links

EDIT: as pointed out in the comments (added solution explanation)

Changing the appendDataToLink function to the following:

  appendDataToLink() {
    // immutability - map the old array to a new array instead of mutating old values
    this.test = this.test.map( e => {
      // get the original link property or the current link if it's not set
      var originalLink = e.hasOwnProperty('originalLink') ? e["originalLink"] : e.link;
      // create new object:
      return {
        ...e, // old object destructured
        originalLink: originalLink, // set original link 
        link: `${originalLink}/rd-${this.generateRandomNumber()}` // create a new link based on the original link
      }
    });
    console.log(this.test);
  }

This uses the link provided as a basis for generating new links and does not require to modify the original object

Upvotes: 2

Waleed Ahmad Qureshi
Waleed Ahmad Qureshi

Reputation: 114

Simplest solution is to maintain a boolean

firstTime: boolean = true;

then modify append function like

appendDataToLink() {
  this.test.forEach((e, i) => {
     if (this.firstTime) {
        if ((this.test.length - 1) === i) { this.firstTime = false; }
        e.link = `${e.link}/rd-${this.generateRandomNumber()}`;
     }
     else {
        e.link = e.link.replace(/.$/, this.generateRandomNumber().toString());
     }
  });
  console.log(this.test);
}

Upvotes: 1

AndyOR
AndyOR

Reputation: 314

I see what you are trying to do. Every time you click the button it will append the random number '/rd-(randNum)' onto the existing string. So if you start with '/abc/def/ghi' and click the button it will add onto the string. Eg:

*ButtonClick*: '/abc/def/ghi' -> '/abc/def/ghi/rd-3'
*ButtonClick*: '/abc/def/ghi/rd-3' -> '/abc/def/ghi/rd-3/rd-7'
*ButtonClick*: '/abc/def/ghird-3/rd-7' -> '/abc/def/ghi/rd-3/rd-7/rd-5'

etc.

If you want to replace the number at the end of the link with a different number you will need to first remove the last number by using substring before adding the new number. Also you can add a new field to know if the link has already been altered or if it is the first time the button has been clicked so you don't lose the '/ghi' part:

appendDataToLink() {
  this.test.forEach( e => {
     if (e.linkAltered === true) {
         e.link = e.link.substring(0, e.link.lastIndexOf("/"));
     }
     e.link = ${e.link}/rd-${this.generateRandomNumber()};
     e.linkAltered = true;
  });
  console.log(this.test);
}

Hope this helps!

Upvotes: 1

Piyush Jain
Piyush Jain

Reputation: 1986

check this code.

First check weather any string ('rd-') present or not, if it is there replace it or if it is not then simply add it.

this.test.forEach( e => {
      if (/rd-[0-9]/.test(e.link)) {
        e.link = (e.link).replace(/rd-[0-9]/, `rd-${this.generateRandomNumber()}`);
      }
      else {
        e.link = `${e.link}/rd-${this.generateRandomNumber()}`
      }
    });

Let me know if you have any doubt.

Upvotes: 0

Rahul Kumar
Rahul Kumar

Reputation: 3157

Take substring from link instead of the link

  const link = e.link.substring(0,12);
  e.link = `${link}/rd-${this.generateRandomNumber()}`

Upvotes: 0

Related Questions