I'm using Ember-data and the JSON API Adapter, I have a particular model widgets which has a nested route /widgets/default, which when posted to will setup a default set of relationships required for adding a new 'widget'. Essentially it's a shortcut method for adding a widget and saves doing lots of posts to separate relation endpoints after creating each widget. The idea is that we want to have numerous preset types of widgets which can be created in one post, each with different sets of relationships.
I have searched the docs for Ember data but could not see anything that would allow this out of the box. Does anyone know if it's possible to use nested routes when creating a record with the JSONApi adapter?
Here's an example of what I'd like to do in pseudo code:
this.get('store').createRecord('widget.default', attrs).save().then((widget)=>{
this.get('router').transitionTo('widgets.edit', widget.id);
});
So calling createRecord on widget.default would trigger it to post the payload to the /widgets/default endpoint, rather than to /widgets.
Maybe the createRecord is what you are looking for.
Related
I'm having a tricky issue with my models and Sails' automatic blueprint matching.
When I post to one of my endpoints, /answer/create, I get a 500 response with validation errors for a different model entirely (the event model).
That endpoint for the event model would be at /event/create, but when I post to that I get a 404.
All of my files were generated with sails generate [model] and don't contain any custom Controller routes.
Has anyone seen this before?
It turned out this was a result of following this screencast:
http://irlnathan.github.io/sailscasts/blog/2013/09/15/sailscasts-answers-ep1-question-about-using-a-service-to-allow-inheritance-in-a-model/
I was inheriting a baseModel via services into more than one other model, so when I ran _.merge(), the changes it made would persist across them both, rendering inconsistencies.
If you want to do this, make sure you use the _.cloneDeep method to clone the base model, otherwise _.merge will affect it and your blueprints/actions won't work as expected.
In the screencast above, this would make line 12 in the user model look like this:
module.exports = _.merge(_.cloneDeep(baseModel) { ... });
Using the Backbone Model and Collection utilities to interact with REST endpoints that return logical entities in your backend system makes sense. For example, endpoints like the following very logically map to models and collections:
GET /posts/:id > Model
GET /posts > Collection
PUT /posts/:id > Model
But what about endpoints that don't really map to a logical entity in your model? For example:
POST /user/login > ?
POST /user/validate-token > ?
It doesn't seem to make sense to force Backbone Models/Collection to work with endpoints like this. Writing some sort of service class using $.ajax or similar seems to be more appropriate. Trouble is we've spent quite a lot of time extending Backbone.sync to respond to particular error codes globally and don't want to duplicate that functionality in a service class too.
How are people interacting with REST endpoints that don't map to models and collections in their Backbone apps?
Going to go ahead and answer my own question here. "mu is too short" got me on the right track in the comments above.
Since Backbone uses $.ajax to handle all its HTTP requests by default you can leverage $.ajaxSetup() and $(document).ajaxError() etc. to handle any app-wide AJAX setup and error responses. Then you're free to write your HTTP service classes using $.ajax too and leverage the same setup for both layers of server communication.
Yes I know there is a plugin called Backbone-Relational but I have a serious problem with its fetchRelated function which, in my opinion, renders it useless for me.
So I was wondering if there are any alternatives? Or do we even need plugins like Backbone-Relational at all? How would you handle following scenario with pure Backbone:
Let's say we have two Backbone models: Company and Person. A Company instance can have many Persons. So company.get('employees') will return an array of Person IDs. If I want to get details of related employees, I'll have to iterate over the array and fetch() each of the Persons from server. But what if those Person instances have been already downloaded? Is there a clean way to make sure that there is no redundancy?
May be we can maintain a Collection for each model and dump every instance we download into it. Then we can download an instance only when it is not present in the Collection. But I think it will make code look horrible.
So please share your experience guys. Thanks!
As you suggested, I would give my Company model a Persons attribute. But you seem to forget collections also have a fetch method (as well as many other methods you'd find pretty useful, as the get method).
Also, as a last thing, I'd like to quote Backbone's doc (regarding the fetch method of Collections):
"Note that fetch should not be used to populate collections on page load — all models needed at load time should already be bootstrapped in to place. fetch is intended for lazily-loading models for interfaces that are not needed immediately: for example, documents with collections of notes that may be toggled open and closed."
I have an array of items populated by an AJAX call in a knockout ViewModel, which displays a few fields of data for each item on a web page.
Now I need to enable the user to click on one item populating a side bar with data which was received from the previous AJAX request (a few fields plus a lot more).
I suppose typically one would take an id and do an item specific AJAX request, routing it through Sammy.js, but we don't need to.
I'm new to knockout; best policy I imagine is to have a ViewModel for the various divs to display the data, but how to get the ViewModels to pass data between themselves? Is this taboo?
Making reference to the other window via the window object?
Using the with: keyword? It keeps cropping up, but I can't see how to apply that in this context.
Perhaps going via Sammy.js, and caching the data in Amplify?
This is an example of drill-down functionality, and I've read a number of StackOverflow Q&A about this but couldn't find up something I can use. I've got up to this stage by following John Papa's PluralSight tutorial.
You may want to go with a pub/sub model either with Amplify's messaging or the library the #RPNiemeyer mentions above. Both are excellent.
However it sounds like you just want to grab the data from the server, then use that data in multiple view models. Perhaps even sharing some of that data in multiple view models. The datacontext concept in my SPA tutorial allows you to host data in the datacontext and reference it from other view models.
You could also use a library like Breeze to help do this (Breeze would replace the datacontext in my SPA ... and be better at it as I will show in an upcoming course).
These are just a few options
You may also want to checkout the "Share an EntityManager" post under "Cool Breezes" in the breeze documentation.
The sharing a single EntityManager is probably all you need. But if you think you need more than one, read "Multiple managers".
IMO The easiest way to do it is to simply pass "params" with an observable containing data to your sidebar component.
http://knockoutjs.com/documentation/component-custom-elements.html#passing-observable-expressions
As was mentioned in comments, the good choice would be to use knockout-postbox
knockout-postbox is a Knockout.js plugin designed to use Knockout's basic pub/sub capabilities to facilitate decoupled communication between separate view models / components.
This allows you to set up simple topic-based communication like:
var ViewModelOne = function() {
this.isEditable = ko.observable();
};
var ViewModelTwo = function() {
this.editable = ko.observable(false);
};
var one = new ViewModelOne();
var two = new ViewModelTwo();
var editableTopic = "myEditableTopic";
one.isEditable.subscribeTo(editableTopic);
two.editable.publishOn(editableTopic)
I have read and even run a sample application that is fully implemented on backboneJS and Django. But am kinda lost how backboneJS is handling this stuff. I need a simple dummy explanation on how backboneJS is receiving the JSON data, building the model, building the collections and listing the data in its view.
Data is displayed in html div tag called "#person"
This is the RESTful/JSON data coming from my server
{"objects":[{"id":"1","name":"John","age":"20", "gender":"male"},{"id":"2","name":"Mary","age":"30","gender":"Female"}]}
Things am looking for in the explanation are;
What is the first function/object created/called by BackboneJS ( entry point )
How does backboneJS tell the views to display the data received?
How does backboneJS model map to the individual fields in the JSON data (id, name, age)
How can i peep in the collections/models created by backboneJS using browser javascript console?
If i have a data entry form with the same fields as the JSON data, using backboneJS, how will i be able to POST the data back to the server, which objects/functions will backboneJS use to perform this task?
Any extra information will be highly appreciated.
Gath
1. What is the first function/object created/called by BackboneJS ( entry point )?
Backbone.js follows MVC architecture. Model defines the actual structural design of model. View defines how the application visually displayed. This view will create the instance of Model and it will be used in the application.
So, in backbone application, Instance of view is created first. When we create an instance of View by calling new myView();, initialize() function will be called first. Model can be instantiated from View as per the requirements.
2. What is the first function/object created/called by BackboneJS ( entry point )?
When you create the instance of model, you can provide the data through that instance. There are getters and setters available for Model.
For example, User is the Model for above JSON. Model is instantiated as below.
var user=new User({“id”:”1”,””name”:”john”,”age”:20,”gender”:”male”});
You need to access the JSON object to define the model.
3.How does backboneJS model map to the individual fields in the JSON data (id, name, age)?
As said before, individual fields can be mapped while instantiating or with the getter and setters of backbone.js
4.How can i peep in the collections/models created by backboneJS using browser javascript console?
You can console the java script objects with toJSON() function. Usually, underscore.js provides more utility functions in backbone.js.
You need to browse through backbone.js documentations.
Addy Osmani did a fine job of explaining that and going even bit more into details down here -> https://github.com/addyosmani/backbone-fundamentals