0

I have this code:

let myArr = [{a: 'Apple'}, {a: 'Banana'}, {a: 'Carrot'}];

let stream = Observable
    .from(myArr)
    .map( el => {
        el.a = 'Coke';
        console.log(`interim----- ${el} ||| ${myArr}`);
        return el;
    });

stream.subscribe( elm = > elm ));   // to trigger the stream

The console output is:

> interim----- {a: "Coke"} ||| [{a: "Coke"}, {a: "Coke"}, {a: "Coke"}]
> interim----- {a: "Coke"} ||| [{a: "Coke"}, {a: "Coke"}, {a: "Coke"}]
> interim----- {a: "Coke"} ||| [{a: "Coke"}, {a: "Coke"}, {a: "Coke"}]

As 'from' streams the array elements one-by-one via 'map', so should the synchronous execution of the anonymous function inside the 'map' alter the myArr objects one-by-one. Therefore my expectation was for a log like this, but it seems that's not the case, why actually?

> interim----- {a: "Coke"} ||| [{a: "Coke"}, {a: "Banana"}, {a: "Carrot"}]   // diff
> interim----- {a: "Coke"} ||| [{a: "Coke"}, {a: "Coke"}, {a: "Carrot"}]     // diff
> interim----- {a: "Coke"} ||| [{a: "Coke"}, {a: "Coke"}, {a: "Coke"}]
zaggi
  • 870
  • 1
  • 7
  • 24
  • 2
    Where do you see such output? https://stackblitz.com/edit/rxjs5-kramvb?file=index.ts – martin Mar 27 '18 at 11:46
  • Is that your exact code for logging the array? I would have expected to see `interim----- [object Object] ||| [object Object],[object Object],[object Object]` – Bergi Mar 27 '18 at 11:49
  • 1
    Btw, using `${myArr}` will print just `[object...]` and not its content. I think what happened in your case is that you output the object `myArr` but in console you see the same instance of the same object so when you inspect it later it's already updated. You can btw output each result but you have to make copies `console.log([...myArr.map(o => Object.assign({}, o))]);` – martin Mar 27 '18 at 11:49
  • @Martin, please have a look here: https://stackblitz.com/edit/angular-s4spr6 – zaggi Mar 27 '18 at 12:31
  • yeah that's exactly what I described above – martin Mar 27 '18 at 12:32
  • @Martin, if I get you right - the explanation is that the execution of the three maps starts in parallel, so as soon as each one of the parallel executions reaches the second line of the anonymous function inside the map, the whole array of objects is already changed... hence the log shows three times the already updated array? – zaggi Mar 27 '18 at 12:42
  • 2
    No, nothing is in parallel in JavaScript. When you output an object to console you're basically outputting just a reference to that object. So you're printing three references to the same object. When you later expand the log in console you're still working with the same instance and therefore you always see the same content. But if you clone the array and the objects inside like I did in my previous comment you'll see three different objects. – martin Mar 27 '18 at 12:45
  • @all, yes the log taken from Chrome console output is somewhat abridged, but I believe it correctly illustrates the question. Sorry for the confusion created. – zaggi Mar 27 '18 at 12:46
  • 1
    @Martin, now clear. By "parallel" I meant more sth like putting the execution to a worker, but as it turns out (I updated the code to experiment and confirm it) it is as you say - the reference to the object which is updated as soon as you unfold the object with the down arrow in the console. Thank you for looking in that – zaggi Mar 27 '18 at 12:58
  • See https://stackoverflow.com/q/23392111/1048572. And please [edit] your post to show the actual code you're using for the logging. – Bergi Mar 27 '18 at 13:35

0 Answers0