webroo / dummy-json

Generates random dummy JSON data in Node.js
MIT License
380 stars 61 forks source link

Pass the JSON as value inside the template #14

Closed devlato closed 7 years ago

devlato commented 8 years ago

Hey guys, is there any way to insert some pre-generated JSON? I.e. I have a JSON like the following:

{
  "id": 137290203,
  "name": "Hello",
  "items": [{
    "id": 4783934,
    "url": "http://some-domain.com/some/resource"
  }, ... here are more items maybe]
}

Is there any way to write it like this?

{
  "id": 137290203,
  "name": "Hello",
  "items": {{items}}
}

And have the items pregenerated using custom helpers?

webroo commented 7 years ago

It depends on where your pre-generated JSON comes from. I'm going to assume it's available as a native JS object for this example.

Imagine this is your template:

{
  "id": 137290203,
  "name": "Hello",
  "items": {{{items}}}
}

(Note the triple brackets around {{{items}}}, this prevents Handlebars from HTML escaping characters, especially the " character which will become ")

Now the code:

var items = [
  { "id": 4783934, "url": "http://some-domain.com/some/resource" },
  { "id": 1234567, "url": "http://other-domain.com/other/resource" }
];

var customMockdata = {
  items: JSON.stringify(items)
};

var output = dummyjson.parse(template, { mockdata: customMockdata });

We're using custom mockdata, which is described in more detail here https://github.com/webroo/dummy-json#using-other-data

Handlebars only deals with strings (and casts objects that are not) which is why we have to convert the items JS object using JSON.stringify. If we didn't do this Handlebars would just generate [Object object].

The only downside to this approach is that the formatting of the output doesn't look so nice, eg:

{
  "id": 137290203,
  "name": "Hello",
  "items": [{"id":4783934,"url":"http://some-domain.com/some/resource"},{"id":1234567,"url":"http://other-domain.com/other/resource"}]
}
webroo commented 7 years ago

An alternative is to keep the template and items in separate files, then load both at runtime, like so:

var template = fs.readFileSync('./template.hbs', {encoding: 'utf8'});
var items = fs.readFileSync('./items.hbs', {encoding: 'utf8'});

var customMockdata = {
  items: items,
};

var output = dummyjson.parse(template, { mockdata: customMockdata });

Again the formatting/whitespace might not look so nice, but at least it will be valid JSON.