DEV Community

Avraam Mavridis
Avraam Mavridis

Posted on

Codetip - Javascript: Hide Dependency to a Data Structure

Many times we encounter situations where our code depends on a complicated data structure or a data structure that has implicit semantics. For example, let’s say we create a chart and the data that we have to use is a response from a server (we can’t change the structure of the response). The response from the server looks like this:

[ ["2018-12-02", 1000], ["2018-11-02", 900], ["2018-10-02", 200], ["2018-09-02", 300] ] 

This structure has an implicit meaning, it is an array of arrays, each of which has two values, the first represents a date and the second one a value. The naive approach is to use this structure directly in our code, like:

class Chart { constructor(data){ this.data = data; } createDomains(){ x.domain(d3.extent(this.data, d => d[0])); // date y.domain(d3.extent(this.data, d => d[1])); // value } createLine(){ d3.line() .x(d => d[0]) // date  .y(d => d[1]); // value } formatDate(){ this.data.forEach(d => { d[0] = parseTime(d[0]); // date }); } } 

The problem with this approach is that, if the server decides to change the order of the values, or introduces a new one in the first or second place of the array, our code we break, let’s say the structure changes to look like:

[ ["Dinos", "2018-12-02", 1000], ["Nikos", "2018-11-02", 900], ["Petros", "2018-10-02", 200], ["Giannis", "2018-09-02", 300] ] 

Now our class is broken, every single method of it is broken. We have to update every method to fix the problem. A better approach would be to not depend on the structure of the response.

class Chart { constructor(data){ this.data = data.map(dataPoint => ({ date: dataPoint[0], value: dataPoint[1], })); } createDomains(){ x.domain(d3.extent(this.data, d => d.date)); y.domain(d3.extent(this.data, d => d.value)); } createLine(){ d3.line() .x(d => d.date) .y(d => d.value) .values(this.data) } formatDate(){ this.data.forEach(d => { d.date = parseTime(d.date); }); } } 

If the server decides to change the passed data structure, we will have to update our code only in a single place, the constructor, leaving every other method untouched.

Top comments (3)

Collapse
 
hdennen profile image
Harry Dennen

@Proxy in JS is great for exactly this. Using a generic proxy decorator, you can create custom proxy classes to instantiate the objects you need from the responses you get.

Collapse
 
avraammavridis profile image
Avraam Mavridis

Needs a polyfill though.

Collapse
 
hdennen profile image
Harry Dennen

Yep. polyfill.io ? never used it but certainly seems cool.