Sometimes working on a Front-end side you need to write your Front-end code while Back-end actions are still not ready.
In this case, you would need to use fixtures on FE side, in order to not mess with BE. I have found relatively new JS ES6 features, as
yieldand
iterator comes in handy for fixtures generation.
Why do I need to generate fixtures for Vue?
For example, I need to feed such a chart with some random data for a given date range. Dates range should go from today and to 10 days in the past.
We also assume, that the data for each chart line will be requested from back-end action by a separate request and merged into some object on the front-end.
Just to make it easier for me, I also have prepared a list of some entity IDs which I display under the chart. When I click on the ID then I simulate a call to back-end and another line added to the chart.
That is how it looks like in action.
Generating fixtures with yield and iterator
Since we are dealing with Vue, I also have created some action in the Vuex store, which calls an API class method.
Inside this method, I just wait for my fixtures provider
Promise to resolve and return the data.
return (new Provider).provide();
The most interesting part is inside the provider itself. Here I have used yieldtogether with the Symbol.iterator functionality to generate random data.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
'use strict'; class Provider { randomIntFromInterval(min, max) { return Math.floor(Math.random() * (max - min + 1) + min); } provide() { return new Promise(resolve => { setTimeout( () => { resolve({ 'status': 200, 'body': [...(new Provider)], 'errors': [], }); }, Math.floor(Math.random() * 2000) ); }); } * provideEntries(k = 10) { let loopDate = new Date(); for (let i = 0; i < k; i++) { const newDate = loopDate.setDate(loopDate.getDate() - 1); loopDate = new Date(newDate); const multiplier = this.randomIntFromInterval(1, 2) === 1 ? -1 : 1; yield { 'category1': { 'score': this.randomIntFromInterval(10, 99) * multiplier, 'responses': this.randomIntFromInterval(100, 999) * multiplier, }, 'category2': { 'score': this.randomIntFromInterval(10, 99) * multiplier, 'responses': this.randomIntFromInterval(100, 999) * multiplier, }, 'date': loopDate.toLocaleDateString(), }; } } [Symbol.iterator] = this.provideEntries; } export default Provider; |
provideEntries is a generator. It works mostly the same as in PHP or any other language which supports generators.
I find it really great how you can assign any function which returns iterable to build-in Javascript
Symbol.iterator functionality and turn your class into an iterable collection.
It works absolutely with any iterable in JS, like arrays, and for generator too.
In provide function, I just declare a new instance of
Provider and use the spread operator
... on it. It makes JS iterate on each iterable collection entry and put it into an array.
In the case of Generator, it will generate all the possible outcome and stop when, according to JS iterators protocol, the generator will return internally something like
return { value: {your object}, done: true };
which is a signal for JS that iteration is over.
Then, in addition, I simulate the waiting time for the response. For that I use
setTimeout a method with some random time to wait and return a
Promise which I can
await in my API class.
When the promise is resolved, I do the response merging with the current Vuex state inside the action method.