6

Is there a best practice or de-facto library for Vue.js when it comes to mapping JSON API responses to "real" javascript Model objects? Coming from iOS Development, there are excellent libraries like JSONModel and MagicalRecord dealing with exactly this matter.

Most Vue.js tutorials/examples I could find just seem to work with the plain JSON responses. IMHO, this gets cumbersome real quick. For instance, when dealing with raw data like date strings which would be better of as real Date objects. So it involves some sort of (de)serialization functionality. Also, it'd be nice to have stuff like Foo.findAll(), Foo.findById(1) or foo.save() to create appropriate calls to the backend service.

I found vue-model which looks promising, but it doesn't seem to have a lot of traction. This makes me wonder, if mapping JSON to objects is just not something a lot of people do in their SPAs? What are alternative approaches?

Tobi Kremer
  • 618
  • 6
  • 22
  • I am struggling with the same question. I found an alternative to models - redux, see https://stackoverflow.com/questions/38445006/redux-state-as-array-of-objects-vs-object-keyed-by-id – Aleksey Razbakov Oct 10 '17 at 22:35

1 Answers1

4

It's not really a common practice. The beauty of working with JSON in a browser based SPA is that parsed JSON is javascript. You don't have to map the values into a typed class.

That said, I understand your point, and at certain times I have built a javascript class whose constructor accepts a javascript object as an "initializer". Then in an API response, you can just map over the response to convert the raw objects into "class" instances with methods, Date properties, etc.

Let's say I have an Animal javascript class.

class Animal {
  constructor(initializer){
    this.name = initializer.name
    this.born = new Date(initializer.born)
  }

  sayMyName(){
    console.log(this.name)
  }
}

In an API response it's extremely simple to make Animal instances from the response.

getAnimals()
  .then(response => this.animals = response.data.map(a => new Animal(a)))

Now your animals data property in Vue has a collection of Animal objects.

Bert
  • 80,741
  • 17
  • 199
  • 164
  • I was hoping that there would be a turnkey solution without having to manually write all sorts of repetitive boilerplate. Also, your solution only solves the (de)serialization problem. I'd still need to manually talk to the server backend for fetching, updating, saving, etc. the resources. But thanks for letting me know that that's more or less the best practice! :) – Tobi Kremer Aug 30 '17 at 08:40
  • 1
    sayMyName method won't be possible to use, because vue works only with flattered objects – Aleksey Razbakov Oct 10 '17 at 22:32
  • 2
    @AlekseyRazbakov Except for the fact it is. https://codepen.io/Kradek/pen/ZXRYvG?editors=1010 – Bert Oct 10 '17 at 22:42
  • Using a constructor method works, but Vue do give a warning like '[Vue warn]: Error in render: "TypeError: instance.SayMyName is not a function"' – Paul Verschoor Aug 15 '19 at 17:03
  • @PaulVerschoor In the example of the answer, I don't see that behavior. But I did notice that your comment capitalizes `SayMyName` and the sample code has it as lower case `sayMyName`. – Bert Aug 15 '19 at 17:09