Faker.js: generate an array of N items?

Created on 12 Aug 2016  路  16Comments  路  Source: Marak/faker.js

Is it possible to generate an array of N items on an api call?

I could not find in readme how to do this.

Most helpful comment

Sorry, this feature is needed.

All 16 comments

You can always do this (unoptimised approach):

var faker = require('faker');

var a = [];

for(var i=0; i<50; i++)
    a.push(faker.fake("{{name.lastName}}, {{name.firstName}} {{name.suffix}}")));

console.info(a);

There ya go, an array of 50 elements.

EDIT: To do this efficiently, simply:

const a = new Array(50).fill(null)
                       .map(e =>
                   e = faker.fake("{{name.lastName}}, {{name.firstName}} {{name.suffix}}"))

@SamuelMarks but it's ugly and awkward. I looked lo and fro in the API for this feature, and came here since I didn't find anything. Of course, the feature is trivial, but would be an interesting one... even a must have at best.

Method signature

faker.random.array( low, high, fn | obj )

Usage

const cart = faker.random.array(1, 5, function (index) {
  return (
    itemId: faker.random.uuid(),
    qty: faker.random.number(10)
  };
});
const cart = faker.random.array(1, 5, {
  get itemId() { return faker.random.uuid(); },
  get qty() { return faker.random.number(10); }
});

Would result in an array from 1 to 5 elements, containing the given objects. In the first case, each array element is the result of the function call. In the second case, each array element is a clone of the specified object.

@yanickrochon -

To me, "ugly and awkward" APIs are those which bloat or take away from the core functionality required.

If you want a more expressive API, feel free to create a new library which takes in faker as a dependency. Lot's of developers do this and it generally works out great. If you make something you feel is useful, I'd be glad to add it to our ReadMe file.

@am1stad -

Just use plain JavaScript. @SamuelMarks has posted a generic solution. If you require a specific faker method to return multiple items, please let me know.

Sorry, this feature is needed.

No updates regarding this?

It seems in fairly high demand.

Let's try adding a very simple and small generator module for creating sets of data.

cc #676

@Marak when you replied that you would not implement it, I did implement my own, and have been using it ever since.

faker.random.array = function randomArray(min, max, obj) {
  const len = faker.random.number({ min, max });
  const array = []

  for (let i = 0; i < len; ++i) {
    array[i] = typeof obj === 'function' ? obj(i) : merge({}, obj);
  }

  return array;
};

For example :

Factory.define('shoppingCart', ShoppingCart, {
  ....
  items: () => faker.random.array(1, 4, () => ({
    itemId: Factory.create('inventoryItem')._id,
    qty: Math.floor(faker.random.number({ min: 1, max: 20 })),
  })),
  ....
});

I did not find a cleaner way of getting the itemId, but perhaps someone else could. This has worked for me, so I did not bother anymore.

I came around to this solution:

// random generator
const generator = (schema, min = 1, max) => {
  max = max || min
  return Array.from({ length: faker.random.number({ min, max }) }).map(() => Object.keys(schema).reduce((entity, key) => {
    entity[key] = faker.fake(schema[key])
    return entity
  }, {}))
}

// your schema
const clientsSchema = {
  id: '{{random.number}}',
  name: '{{company.companyName}} {{company.companySuffix}}',
  address: '{{address.streetAddress}}',
  phone: '{{phone.phoneNumber}}',
  email: '{{internet.email}}'
}

// generate random clients between 5 and 20 units, based on client schema defined above
const data = generator(clientsSchema, 5, 20)

/*
data looks like this:

[ { id: '92447',
  name: 'Wintheiser Group Group',
  address: '566 Leonardo Loop',
  phone: '025.415.9443 x5894',
  email: '[email protected]' },
{ id: '42354',
  name: 'Larson Inc and Sons',
  address: '3089 Waelchi Keys',
  phone: '711.874.8437 x58199',
  email: '[email protected]' },
{ id: '33162',
  name: 'Funk, Moore and Gibson Group',
  address: '2855 Olson Skyway',
  phone: '353-871-3169 x2456',
  email: '[email protected]' },
{ id: '99311',
  name: 'Welch and Sons LLC',
  address: '4290 Raynor Viaduct',
  phone: '(865) 134-0699 x15482',
  email: '[email protected]'},
{ id: '6402',
  name: 'Jast LLC and Sons',
  address: '28523 Cyril Islands',
  phone: '(585) 676-0646',
  email: '[email protected]'},
{ id: '95438',
  name: 'Collier LLC Inc',
  address: '11800 Yasmine Terrace',
  phone: '(069) 465-5747 x789',
  email: '[email protected]'},
{ id: '61514',
  name: 'Mitchell Group and Sons',
  address: '636 Cruickshank Fork',
  phone: '464-628-4065',
  email: '[email protected]'} ]

*/

Hope this help.

This generator function above should be part of faker IMO.

This is relevant https://github.com/danibram/mocker-data-generator, and uses this library under the hood.

Faker function based on parameters.

const rating = { min: 1, max: 5, precision: 0.1 }

const generator = (schema, min = 1, max) => {
    max = max || min
    return Array.from({ length: faker.random.number({ min, max }) }).map(() => Object.keys(schema).reduce((entity, key) => {
        entity[key] = schema[key].call(this)
        return entity
    }, {}))
}

const roomsSchema = {
    id: faker.random.uuid,
    name: faker.random.arrayElement.bind(null, ['Deluxe suite', 'Mini Suite', 'Executive Floor', 'Single', 'Double', 'Triple', 'Studio']),
    rating: faker.random.number.bind(null, rating)
}

I updated @wilk 's answer to include nested objects

// generator
const generator = (schema, min = 1, max) => {
  max = max || min;
  return Array.from({
    length: faker.random.number({
      min,
      max,
    }),
  }).map(() => {
    const innerGen = (anySchema) => Object.keys(anySchema).reduce((entity, key) => {
        if (
          Object.prototype.toString.call(anySchema[key]) === '[object Object]'
        ) {
          entity[key] = innerGen(anySchema[key]);
          return entity;
        }
        entity[key] = faker.fake(anySchema[key]);
        return entity;
      }, {});

    return innerGen(schema);
  });
};

// your schema
const clientsSchema = {
  id: '{{random.number}}',
  name: '{{company.companyName}} {{company.companySuffix}}',
  contact: {
    address: '{{address.streetAddress}}',
    phone: '{{phone.phoneNumber}}',
    email: '{{internet.email}}',
  },
};

// generate random clients between 2 and 5 units, based on client schema defined above
const data = generator(clientsSchema, 2, 5);

// data looks like this:
[
  {
    id: '92447',
    name: 'Wintheiser Group Group',
    contact: {
      address: '566 Leonardo Loop',
      phone: '025.415.9443 x5894',
      email: '[email protected]',
    },
  },
  {
    id: '42354',
    name: 'Larson Inc and Sons',
    contact: {
      address: '3089 Waelchi Keys',
      phone: '711.874.8437 x58199',
      email: '[email protected]}',
    },
  },

  ...
];

Piggy backing @its-tayo and @wilk ... added an if catch so that you don't have to include the interpolated strings '{{random.number}}' and can just include the method calls if you like: random.number(10)

const clientsSchema = {
  id: random.number(), // this will work as well
  name: '{{company.companyName}} {{company.companySuffix}}',
  contact: {
    address: '{{address.streetAddress}}',
    phone: '{{phone.phoneNumber}}',
    email: '{{internet.email}}',
  },
};
const generator = (schema, min = 1, max) => {
  max = max || min;
  return Array.from({
    length: faker.random.number({
      min,
      max
    })
  }).map(() => {
    const innerGen = anySchema =>
      Object.keys(anySchema).reduce((entity, key) => {
        if (Object.prototype.toString.call(anySchema[key]) === '[object Object]') {
          entity[key] = innerGen(anySchema[key]);
          return entity;
        }
        entity[key] = faker.fake(anySchema[key]);
        if (entity[key] === 'string parameter is required!') { // added this 'if' statement
          entity[key] = anySchema[key];
        }
        return entity;
      }, {});

    return innerGen(schema);
  });
};

Due to popular demand, we will be adding a new set of generator methods to faker.js in the next major release.

I do like some of the code I have seen posted in this thread and we also have some decent methods which exist as PRs.

If anyone would like to see their generator or helper methods added please feel open a PR or just post them here.

@Marak Cool. I still think that my implementation is pretty darn obvious + efficient:
https://github.com/Marak/faker.js/issues/399#issuecomment-240339604

I'll try to bump what i have in mind based on @wilk and @its-tayo solution

const fakerGen = (schema, min = 1, max) => {
    max = max || min;
    return Array.from({
        length: faker.random.number({
            min,
            max
        })
    }).map(() => {
        const innerGen = anySchema =>
            Object.keys(anySchema).reduce((entity, key) => {
                if (typeof anySchema[key] === 'function') {
                    entity[key] = anySchema[key]();
                    return entity;
                }

                if (Object.prototype.toString.call(anySchema[key]) === '[object Object]') {
                    entity[key] = innerGen(anySchema[key]);
                    return entity;
                }

                entity[key] = faker.fake(anySchema[key]);
                return entity;
            }, {});

        return innerGen(schema);
    });
};

So instead of calling it, just give it a function

const clientsSchema = {
  id: '{{random.number}}',
  name: '{{company.companyName}} {{company.companySuffix}}',
  contact: {
    address: '{{address.streetAddress}}',
    phone: '{{phone.phoneNumber}}',
    email: '{{internet.email}}',
  },
  //function call
  blood_type: () => {
    return random.arrayElement(['A', 'B', 'AB', 'O']);
  },
};
Was this page helpful?
0 / 5 - 0 ratings

Related issues

JeffBeltran picture JeffBeltran  路  5Comments

ghost picture ghost  路  4Comments

noyessie picture noyessie  路  4Comments

minhchu picture minhchu  路  3Comments

adoyle-h picture adoyle-h  路  3Comments