0

I was working on the Android and found Gson as a handy utility to convert JSON objects into Java objects. Since I am a big fan of Object Oriented architecture, I am trying to optimize angular code using OO architecture. Every object is mapped to a factory. I am wondering if there is any plugin in javascript or angular that can convert JSON to Angular Objects. e.g. If I have a card factory in Angular

app.factory('Card', [function() {
    function Card(cardData) {
      if (cardData) {
        this.setData(cardData);
      }else{
        this.new();
      }
    };


   Card.prototype = {

     new: function(){
      var cardData = {
        title: 'Add your recommendations',
     }
     this.setData(cardData);
   }
  };
  return Card;
}]);

and I am getting JSON data like this

{card: {title: 'demo_title'}}

it should map it automatically like GSON does. I can create a new module to do that, just wondering if someone already did that.

Uzair
  • 716
  • 9
  • 16
  • It might be a bit of a silly of mine but, do you know javascript has its own JSON parse mechanism right? Like `JSON.parse("{\"card\": {\"title\": 'demo_title'}}") => {card: {title: 'demo_title'}};` so you'd like to instantiate a class with the json string is that correct? – lenilsondc Oct 25 '17 at 11:04

1 Answers1

0

You don't need to create something to work like GSON because JSON has native support on javascript via JSON.parse("{\"card\": {\"title\": 'demo_title'}}" which will produce a javascript object like {card: {title: 'demo_title'}}. In addition, the angularjs' $http service, parses your JSON internally, so you don't even have to think about it.

However, what I think you are looking for, is an approach for using data from the server and instantiate a class from the parsed JSON. A regular approach for that, is using a class which in its constructor you provide the raw object and merge it into its properties. It's convenient to use angular.extend() but you can do it manually if you prefer.

It'd be something like this:

function Card(data) {
    angular.extend(this, data);
}

var myCard = new Card({ title: 'demo_title' });

Furthermore, if you want to keep a more reliable model, you can declare a class to work as the object to hold the data, and add methods to retrieve and post data to the server.

angular.module('app')
  .factory('Card', ['$http', function CardFactory($http) {

    var Card = function (data) {
      angular.extend(this, data);
    }

    Card.get = function (id) {
      return $http.get('https://my.api/cards/' + id).then(function(response) {
        return new Card(response.data.card);
      });
    };

    Card.all = function () {
      return $http.get('https://my.api/cards').then(function (res) {
        return res.data.cards.map(function (x) {
          return new Card(x);
        });
      });
    };

    Card.prototype.create = function () {
      var card = this;

      return $http.post('https://my.api/cards', card).then(function(response) {
        card.id = response.data.card.id;
        return card;
      });
    }

    return Card;
  }]);

So that you can use it like this:

angular.module('app')
  .controller('CardCtrl', ['Card', function CardsCtrl(Card) {
    // get a card
    this.card = Card.get(1);

    // create a new card
    this.newCard = function newCard() {
      var card = new Card({ title: 'new_card' });
      card.create();
    };
  });

Ref.: Recommended way of getting data from the server

lenilsondc
  • 9,590
  • 2
  • 25
  • 40
  • Thanks @Lenilson for your detailed answer, I am actually using this and it works fine for the single record. when you get the list of records then it becomes tricky since you have to iterate it and convert each record as an object. Ideally, GSON does the same. That's why wondering to save one step in code :) – Uzair Oct 26 '17 at 06:54
  • @Uzair Okay, again, you don't have to care about the serialization, so after response is all javascript, you can just use `Array.prototype.map` for example. It just depend on your coding from now on. I'll update the factory to exemplify the collection case. – lenilsondc Oct 26 '17 at 10:34