yodalr
yodalr

Reputation: 10912

Angular 2: merging one observable "inside" another

On page load I load this data into the template as items:

{
    "id": "1",
    "name": "Leonardo",
    "weapon": "sword",
},
{
    "height": "2",
    "name": "Donatello",
    "weapon": "stick",
},

I load the data using this in my component:

this.dataSubscription = this.dataService.getAllTurtles().subscribe(res => this.turtles = res);

Each item also has a button "LOAD MORE DATA". When I click on it, it loads some extra data that belongs to that specific item:

this.dataSubscription = this.dataService.getData(id).subscribe(res => this.singleData = res);

Loads me this

{
    "favoritePizza": "Hawai",
}

Now, I want to merge this data into the original data stream, so I'd have:

{
    "id": "1",
    "name": "Leonardo",
    "weapon": "sword",
    "favoritePizza": "Hawai"
},
{
    "id": "2",
    "name": "Donatello",
    "weapon": "stick",
}

But I'm unsure how to concat the arrays that way. Currently when I do it with concat:

this.dataSubscription = this.dataService.getData(id).subscribe(res => this.turtles = this.turtles.concat(res));

I just get concated arrays:

{
    "id": "1",
    "name": "Leonardo",
    "weapon": "sword",
},
{
    "id": "2",
    "name": "Donatello",
    "weapon": "stick",
}
{
    "favoritePizza": "Hawai"
}

How do I access a specific item inside the array using it's id and add to it data I have loaded later on?

Upvotes: 2

Views: 92

Answers (3)

Kliment Ru
Kliment Ru

Reputation: 2137

this.dataService.getAdditionalData(id)
  .subscribe(data => {
    this.turtles = this.turtles.map(i => {
      if (i.id !== id) {
        return i;
      }
      return { ...i, ...data };
    })
  })

example https://stackblitz.com/edit/angular-tl4mt1?file=app%2Fapp.component.ts

Upvotes: 1

olivier cherrier
olivier cherrier

Reputation: 274

Maybe your call done from button "LOAD MORE DATA"

this.dataSubscription = this.dataService.getData(id).subscribe(res => this.singleData = res);

should be named

this.dataSubscription = this.dataService.getTurtle(1).subscribe(res => this.singleData = res);

With getTurtle that return an Observable to the Object Turtle, which contain, by design of document into mongoDB, the details of Turtle, including the favorite pizza:

{
  "id": "1",
  "name": "Leonardo",
  "weapon": "sword",
  "favoritePizza": "Hawai"
}

Upvotes: 0

Devang Naghera
Devang Naghera

Reputation: 706

You can do something like this

var a1 = [{
  "id": "1",
  "name": "Leonardo",
  "weapon": "sword",
  "favoritePizza": "Hawai"
}, {
  "id": "2",
  "name": "Donatello",
  "weapon": "stick",
}]

var a2 = {
  "favoritePizza": "Hawai",
}

a1 = a1.map((e) => {
  return e.id === "1" ? Object.assign(e, a2) : e
})

console.log(a1);

There might be better options though!!!

Upvotes: 0

Related Questions