Integrating Parse Data with ng-model in AngularJS

Parse Data Cloud Plus AngularJS

This past week I was working on a project where I had to integrate Parse Data with AngularJS. I ended up having to write my own solution to get them to play nicely together, which is what I wanted to share with you today.

First, Some Background On Parse

"Parse allows your team to focus more on creating a great user experience and forget server maintenance and complex infrastructure. Instantly add push notifications, data storage, social integration, and more the moment you integrate a Parse SDK into your app."

The excerpt above is from the home page on the Parse website and the statement couldn't be truer. After using Parse for the past week I have been extemely happy with the platform. Their Javscript SDK was very simple to get started working with. I was able to sign up and have an app boostrapped in under 5 minutes. The simplicity of this process immediately attracted me to the platform.

Unfortunately, Parses object structure is based off of Backbone, which inherently doesn't play nice with Angular. Suffice to say, Backbone uses getter/setters where as Angular binds to the properties of objects.

I looked around for solutions already available and found one project that was interesting, but it didn't work with ng-model. So I decided to expand upon that and write my own solution.

parse-angular

There were some things I liked in the project I had found, so I decided to use that as a starting point. I've posted the code on github, so please feel free to let me know how you think I can improve it. It's also worth noting that it would probably be better long term to implement a solution with their REST API and native angular directives, but there was so many convenient features built in to the Javascript SDK that I didn't want to reinvent the wheel this time around.

Instead the code dynamically creates an object with properties that are tied to the original Parse object. Using the Object.defineProperty function in Javascript, allows me to define object properties with custom getter/setters that I use to pull from the underlying Parse data source.

Object.defineProperty(this, propName, 
{
    get : function(){ return parseObject.get(propName); },
    set : function(value){ parseObject.set(propName, value); }
});

Creating A New Object

One of the great things about Parse is the schemaless nature of its data, allowing us to setup whatever key-value pairs we want within our app. All we have to do is define an object and property list and save it to Parse.

//create new contact record from string
$scope.newContact = new ParseObject('Contact', ['firstName','lastName','email']);

/* OR */

//create new contact record from parse object instance
var Contact = Parse.Object.extend('Contact');
$scope.newContact = new ParseObject(new Contact(), ['firstName','lastName','email']);

We can now bind $scope.newContact to any directive with ng-model to modify or display the object properties.

<input type="text" ng-model="newContact.firstName" />
<input type="text" ng-model="newContact.lastName" />
<input type="text" ng-model="newContact.email" />
<button ng-click="newContact.save()">Save

That's it. Assuming the Class Contact didn't already exist, upcon clicking the Save button, a new Class will be created in Parse with the name of Contact and have the custom fields firstName, lastName, & email. It's important to note that Parse locks in the data type on fields with the data type of the first record that is saved.

Retrieving records

var query = new Parse.Query(Parse.Object.extend('Contact'));
ParseQuery(query, {functionToCall:'first'}).then(function(obj){
    $scope.newContact = new ParseObject(obj, ['firstName','lastName','email']);
});

This creates a query to retrieve the first record from the Contact class. The returned object is then wrapped in an instance of my ParseObject function allowing the fields to be accessed via the object properties.

Once again, you can find the code and an example project on github and I hope this was helpful!

Vote on HN


comments powered by Disqus