-1

I am running into an issue where I have an array with mysterious duplicates.

In firebase, my object contains the array

{
   ink_colors:
      0: 'Mauve',
      1: 'Mineral',
      2: 'Mocha',
      3: 'Navy' 

}

Firebase web console:

enter image description here

When the object is received by my React app, the console reports

console.log(snapshot.val().ink_colors);

> Array(4) [ "Mauve", "Mineral", "Mocha", "Navy" ]

BUT

when the array is accessed, it apparently has 6 items

temp1.ink_colors
// => [ "Mauve", "Mineral", "Mocha", "Navy", "Mauve", "Mauve" ]

In Chrome 72.0.3626.121 Chrome console screenshot

In Firefox 65.0.1 Firefox console screenshot

Trying to debug this issue with a console log and debugger, I save the console output at a global variable temp1 and get two different results:

function receive(payload){
   console.log(payload);
   debugger;
}
> payload.ink_colors
< (4) ["Mauve", "Mineral", "Mocha", "Navy"]

> temp1.ink_colors
< (6) ["Mauve", "Mineral", "Mocha", "Navy", "Mauve", "Mauve"]

which tells me the issue is not the typical firebase array pitfall of having unexpected empty array values.

NPM Packages:

react: 16.8.2

redux: 4.0.1

firebase: 5.7.2

  • 5
    Well is something else accessing it, setting it? Hard to know what is going on without seeing more code. – epascarello Mar 18 '19 at 15:44
  • 4
    It seems clear to me that something is adding two additional `"Mauve"` entries after the time you log the array. The one-line `log` output shows the array as it exists at the time of logging, while the expansion of that entry shows the array at the time of expansion. The array is gaining additional entries between the time you log it and the time you expand it. I suspect it's not possible to say what's performing those unwanted additions without seeing more code. – apsillers Mar 18 '19 at 15:45
  • 1
    You should proxy your array and debug on a method called. – Seblor Mar 18 '19 at 15:46
  • Can you show the entire code you are using to read the database? not only `snapshot.val().ink_colors`, but how you get `snapshot` – Renaud Tarnec Mar 18 '19 at 15:48
  • 1
    We're missing the complete code that reproduces the problem here. Telling us that it is correct in one place, but not in another is a good problem statement, but isn't good enough to be able to help you. Try to reproduce the problem in a single piece of standalone code that anyone can easily run. See [how to create a minimal, complete, verifiable example](http://stackoverflow.com/help/mcve). – Frank van Puffelen Mar 18 '19 at 15:51
  • 1
    See [this fiddle](https://jsfiddle.net/kdfg1yeq/) for a demonstration of @apsillers comment above. Console logs a five-item array, expansion shows six. – Tyler Roper Mar 18 '19 at 15:52
  • console.log commands are buffered and not synchronous. When the log actually executes, the array size has changed because of the push command. If you switch that to `console.log(array.slice(0));` you'll see the correct count. That doesn't reproduce the behavior described by the op. Still need a minimal repro to know why there are 2 extra `Mauve` in the list. No code here creates that condition. – Kato Mar 18 '19 at 15:59
  • See my answer how you can fix it by debugging. – Bhojendra Rauniyar Mar 18 '19 at 16:27
  • Ah, I did not realize console.log would log the current value and then display a different value later. Indeed, a method was pushing entries onto the end of the array, which could have been avoided by using .slice() to copy the array. I suspected as much, but thought the problem was deeper because of the unexpected (to me) logging. Thanks for your help! – Michael O'Connell Mar 18 '19 at 17:03

2 Answers2

0

Please make sure that you are not adding the elements twice, in case of doing it right you could improve filtering the resulting array to a new array of unique elements.

Take a look at:get-all-unique-values-in-a-javascript-array-remove-duplicates

Also this could be a problem with the method whose adding the elements in firebase.

0

It seems you have somewhere the code changing the value. Take this for example:

let arr = ["Mauve", "Mineral", "Mocha", "Navy"];
debugger
// somewhere in the code, the arr is being modified
arr.length = 6;
arr.fill('Mauve', -2)
// where you are trying to log arr
console.log(arr)

Now, open the developer tool and run the above snippet, you'll see the length of arr is 4. But in fact, you can see the length of arr is 6 and you noticed it is modified after the debugger is being used.

And if you're not able to find the culprit, then you may try a dirty fix using Object.freeze:

let arr = ["Mauve", "Mineral", "Mocha", "Navy"];
Object.freeze(arr)
// somewhere in the code, the arr is being modified
arr.length = 6;
arr.fill('Mauve', -2)
// where you are trying to log arr
console.log(arr)

After then you can be able to see the actual problem containing the line that file is used such modification. For eg. here in the snippet, you can see:

Error: {
  "message": "Uncaught TypeError: Cannot assign to read only property '2' of object '[object Array]'",
  "filename": "https://stacksnippets.net/js",
  "lineno": 17,
  "colno": 5
}

So now, you know where it is. And you can finally resolve the issue and then remove the Object.freeze again.

Bhojendra Rauniyar
  • 83,432
  • 35
  • 168
  • 231