0

I'm fetching markdown from an API and I want to use it in my vuejs app.

I want to have access to the markdown and the converted data.

async getNotes() {
  var regxHighlights = /id:\b([0-9]+)\b/g;
  var regxNotes = /id-\b([0-9]+)\b/g;
  fetch(`/books/${this.id}/notes`).then(res => res.json()).then(res => {
    var data = res.map(n => {
      n.note = converter.makeHtml(n.note)
      n.note = n.note.replace(regxHighlights, `<b class="ref noteRef" style="user-select: none;" data="id$1" >id:$1</b>`);
      n.note = n.note.replace(regxNotes, `<b class="ref noteRef" style="user-select: none;" data="id-$1" >id-$1</b>`);
      return n
    })
    this.notes = data
    this.rawNotes = res
  })
},

The problem is that res has been changed! So data and res are the same thing. That shouldn't happen right!

Phil
  • 157,677
  • 23
  • 242
  • 245
relidon
  • 2,142
  • 4
  • 21
  • 37
  • Does this answer your question? [What is the most efficient way to deep clone an object in JavaScript?](https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript) – yqlim Sep 09 '20 at 01:28
  • `data` and `res` are distinct arrays of the same references that you modified in the `map` callback, so they are effectively the same thing – Matt Sep 09 '20 at 01:28
  • @Phil both `res` and `data` are the same. `res` should be markdown and `data` should be HTML, but they are both html – relidon Sep 09 '20 at 01:29
  • Yep, sorry. Took me a minute to see what was going on – Phil Sep 09 '20 at 01:29
  • As @Matt explained, quick solution just make a copy of the res object , like this let data = Object.assign({},res); – altoqueperro Sep 09 '20 at 01:49

2 Answers2

0

It sounds like the response is an array of objects. When you do res.map(n, each n is a reference to one of the original objects. For example, on the first iteration, n === res[0]; changing n will change res[0].

It looks like making a shallow copy of the object should work here:

var data = res.map((originalObj) => {
  const newObj = { ...originalObject };
  newObj.note = converter.makeHtml(n.note)
      .replace(regxHighlights,
                          `<b class="ref noteRef" style="user-select: none;" data="id$1" >id:$1</b>`)
      .replace(regxNotes,
                          `<b class="ref noteRef" style="user-select: none;" data="id-$1" >id-$1</b>`);
  return newObj;
})

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • Yes!!! I kept trying to do `const newObj = { ...res };` and loop `newObj` and didn't work. Great, – relidon Sep 09 '20 at 01:39
0

Because map only creates new array, it doesn't copy element. n reference the original object.

MDN Docs:

The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.

LingSamuel
  • 496
  • 5
  • 10