Home > Blockchain >  Javascript how to create unique id on object that is pushed into an array
Javascript how to create unique id on object that is pushed into an array

Time:06-24

I want to push an object into an array a random amount of times and have each object have it's own unique id. Currently, I am able to push that object into the array a random amount of times but am getting "Each child in a list should have a unique "key" prop." error. When I console.log the array, I do see that every object has the same key.

I have some code set up to generate a unique ID, but it doesn't seem to work.

Here is my data object that I am calling:

let id = Math.random().toString(16).slice(2);

export const data = {
    key: id,
    asylumOffice: 'AyS',
    citizenship: 'h',
    raceOrEthnicity: 'other',
    caseOutcome: 'pending',
    completion: 'n',
    currentDate: 'f',
  };

And the code where I am calling it and generating a random amount:

let dataArray = [];
let randomNum = Math.floor(Math.random() * 10);
for (let i = 0; i < randomNum; i  ) {
  dataArray.push(data);
} 

I understand that the for loop is pushing the same instance of data and that's why they all have the same id, but I don't know how to make it so that they each have their own. Any suggestions?

CodePudding user response:

If you want to generate really unique id’s, you should use uuid.

Here is the npm package. It is fairly easy to setup and use.

CodePudding user response:

From the React docs for Lists and Keys:

The best way to pick a key is to use a string that uniquely identifies a list item among its siblings.

So keys don't need to be random: they just need to be unique amongst siblings. And for that reason, using a plain integer for a fixed key is just fine:

const count = Math.floor(Math.random() * 10);

const dataArray = [...new Array(count).keys()].map(key => ({...data, key}));

CodePudding user response:

simplelly call Math.floor(Math.random() * 10) on every push and use spread syntaxs

// changed let to const cause it's not re-assigned
const dataArray = [];
for (let i = 0; i < randomNum; i  ) {
  // this copies the original data and overwrite key to a new randomly
  // generated key
  dataArray.push({ ...data, key: Math.floor(Math.random() * 10) });
}

CodePudding user response:

If you don't mind taking the chance of random number collision on the ids, then just spread new random ids into your objects as you build the array. I might do it like this:

const randomCopies = (data) => [...Array (Math .floor (Math .random () * 10))] .map(() => ({
  id: Math .random() .toString(16) .slice (2), 
  ... data
}))

const data = {asylumOffice: 'AyS',  citizenship: 'h',  raceOrEthnicity: 'other',  caseOutcome: 'pending', completion: 'n', currentDate: 'f'}

console .log (randomCopies (data))
.as-console-wrapper {max-height: 100% !important; top: 0}

But if this is just to avoid collisions, then a sequential number will be cleaner, and you could do this instead:

const seqNumber = ((n) => () =>   n) (0)

const randomCopies = (data) => [...Array (Math .floor (Math .random () * 10))] .map(() => ({
  id: seqNumber(), 
  ... data
}))

const data = {asylumOffice: 'AyS',  citizenship: 'h',  raceOrEthnicity: 'other',  caseOutcome: 'pending', completion: 'n', currentDate: 'f'}

console .log (randomCopies (data))
.as-console-wrapper {max-height: 100% !important; top: 0}

In either case, this will choose a random number of copies from 0 to 9. If you want from 1 to 10, then you will need to add 1 to the results of the Math.floor call.

  • Related