18

I am using the faker.js library to generate random data and I have a couple of factory functions that generate a series of user data:

const createUser = () => {
  return {
    name: faker.name.findName(),
    email: faker.internet.email(),
    address: faker.address.streetAddress(),
    bio: faker.lorem.sentence(),
    image: faker.image.avatar(),
  };
};

const createUsers = (numUsers = 5) => {
  return Array(numUsers).fill(createUser());
};

let fakeUsers = createUsers(5);
console.log(fakeUsers);

The problem with this Array.fill approach is that it returns the same data n number of times. I want 5 different users to be returned from my factory.

How do I do this?

3
  • 1
    Why do you not want to use a loop? Commented Mar 17, 2017 at 15:45
  • 1
    no reason - just want to know alternate ways of doing things with Array.fill Commented Mar 17, 2017 at 15:45
  • 1
    Set aside the Array functors there are tons of other ways to loop in JS. You may even do this job recursively. Commented Mar 17, 2017 at 15:59

5 Answers 5

33

Array.from allows you to create an array and initialize it with values returned from a callback function in one step:

const createUsers = (numUsers = 5) => {
    return Array.from({length: numUsers}, createUser);
}
Sign up to request clarification or add additional context in comments.

1 Comment

No empty fills, no maps, just exactly what should be done. Thanks!
7

Create an array with blanks, and then use .map() to create users:

const createUsers = (numUsers = 5) => {
    return Array(numUsers)
        .fill(null)
        .map(createUser);
}

Comments

5

You can now do this with the multiple helper much more easily as of the latest version (v8.0.0):

const createUser = () => {
  return {
    name: faker.person.fullName(),
    email: faker.internet.email(),
    address: faker.location.streetAddress(),
    bio: faker.lorem.sentence(),
    image: faker.image.avatar(),
  };
};

faker.helpers.multiple(createUser, { count: 5 })

See the docs for more info: https://fakerjs.dev/api/helpers.html#multiple

1 Comment

name and address are deprecated, use person and location respectively.. instead of name.findName() use person.fullName() instead of address.streetAddress() use location.streetAddress()
4

Creating an array via the Array constructor will yield an non mappable (or iterable for that matter) array.

This happens because the constructor will give you an array with X uninitialized values, causing map to fail. Using fill to initialize the values, even if initialized to null or undefined, will work:

const createUser = () => {
  return {
    name: faker.name.findName(),
    email: faker.internet.email(),
    address: faker.address.streetAddress(),
    bio: faker.lorem.sentence(),
    image: faker.image.avatar()
  }
}

const createUsers = (numUsers = 5) => {
  return new Array(numUsers)
    .fill(undefined)
    .map(createUser);
}

let fakeUsers = createUsers(5)
console.log(fakeUsers)

https://jsbin.com/punesorico/edit?html,js,console

1 Comment

nice explanation
1

Here is another way of doing this job by a TCO recursive function;

function getFakeObject(){
  return Array(5).fill()
                 .reduce(o => Object.assign(o,{[String.fromCharCode(...Array(5).fill().map(_ => ~~(Math.random()*26)+65))] : String.fromCharCode(...Array(5).fill().map(_ => ~~(Math.random()*26)+97))}),{});
}

function makeFakeObjectsArray(n, r = []){
 return n ? makeFakeObjectsArray(n-1,(r.push(getFakeObject()),r)) : r;
}

console.log(makeFakeObjectsArray(5));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.