Backbone: pluck models with an array of IDs, and save them - backbone.js

So I have an array of IDs:
var myIDs = [1,5,9];
I have a collection that I want to search through, and pluck from. I thought I could do something like the following:
var searchResults = myCollection.where({"uID" : myIDs});
Of course that won't work, but there must be a way to achieve something similar.
Once I have the selected models, the plan is to edit the contents of, then save. Am I correct in assuming I can save the whole batch by doing the following?
myCollection.reset(searchResults);
I'm a total n00b to Backbone, obviously.

You can use Collection.filter to compare each item against the array:
var searchResults = myCollection.filter(function(model) {
return myIDs.indexOf(model.id) != -1;
});
("Where" is like a special case of "filter", with a specific iterator -- it compares the properties of each model with the hash set you provide.)
As far as saving, if you mean replacing the items in the collection, then yes, you can use reset for that. (Note that "save" in Backbone parlance normally means syncing model updates back to the server.)

Related

How do I modify/enrich an Eloquent collection?

I'm using eloquent relationships.
When I call $carcollection = $owner->cars()->get(); I have a collection to work with. So let's say that I have, for this particular owner, retrieved three cars. The collection is a collection of three arrays. Each array describes the car.
This is all working fine.
Now I want to add more attributes to the array, without breaking the collection. The additional attributes will come from a different source, in fact another model (e.g. servicehistory)
Either I retrieve the other model and then try merge() them, or I try manipulate the arrays within the collection without breaking the collection.
All this activity is taking place in my controller.
Is one way better than another, or is there a totally different approach I could use.... perhaps this logic belongs in the model themselves? Looking for some pointers :).
Just to be specific, if you do $owner->cars()->get(); you have a collection of Car Models, not array.
That have been said, you can totally load another relation on you Car model, using
$carcollection = $owner->cars()->with('servicehistory')->get();
$carcollection->first()->servicehistory;
You can try to use the transform method of the collection.
$cars = $owner->cars()->get();
$allServiceHistory = $this->getAllService();
$cars->transform(function($car) use($allServiceHistory) {
// you can do whatever you want here
$car->someAttribute = $allServiceHistory->find(...):
// or
$car->otherAttribute = ServiceHistoryModel::whereCarId($car->getKey())->get();
});
And this way, the $cars collection will be mutated to whatever you want.
Of course, it would be wiser to lazy load the data instead of falling into an n+1 queries situation.

Backbone.js collection getting multiple models

You can get a model from the collection by using collection.get(id);
but i want to get mulitple models. The get only gets 1 models.
I now use this piece of code, but it doesn't look pretty or feels good for performance. Anyone knows a better way to select an array of models from the collection?
var models = this.collection.filter(function(model){
return _.indexOf([1,2,3,4], model.get('id')) > -1;
});
Since you just need 4 items, your code iterate whole collection.
Following code is better performance by iterating only size 4 array.
var models = _.map([1,2,3,4], function(id) {
return collection.get(id);
});

replace collection in a view

I want to replace a collection inside a view. I use the reset command like this:
var maColl=mContent.get(ici).get("svgParameterList");
msvgParameterListView.collection.reset(maColl);
A JSON.stringify gives this :
maColl
[{"id":"x","name":"x"},....{"id":"style","name":"style"}]
msvgParameterListView.collection
[[{"id":"x","name":"x"},....{"id":"style","name":"style"}]]
Now, i have my collection in an array, so when i render it return null value.
How to change array of collection into collection ?
In short, how to make msvgParameterListView.collection equal to maColl ?
Note the [[ ]] for the new collection.
Note maColl is a collection inside another collection.
If I understand correctly, you are trying to reset a collection with the models of another collection? collection.toJSON is your friend:
toJSON collection.toJSON()
Return an array containing the attributes hash of each model in the collection. This can be used to
serialize and persist the collection as a whole. The name of this
method is a bit confusing, because it conforms to JavaScript's JSON
API.
which could be applied like this
msvgParameterListView.collection.reset(maColl.toJSON());
Or if you want to keep a reference to the original models, pass maColl.models
msvgParameterListView.collection.reset(maColl.models);
Passing directly a collection to reset will only confuse Backbone.

How to alter a backbone.js collection using equivalent of .slice(start, end)

My Backbone Collection receives 30 models on fetch().
I have tried
newColl=origColl.first(2);
to return a new Collection. When I try to pass to the View it won't work.
Is there anyway to do this using an underscore.js method?
Your code doesn't work likely because first(n) returns an array while your view is expecting a collection. You need to wrap it like this:
var newColl = new Backbone.Collection(origColl.first(2));
For a general "slice" you can use find in conjunction with _.range:
var newColl = new Backbone.Collection(origColl.find(_.range(start, end));
Naturally, tou can use your own collection class instead of Backbone.Collection.
See the documentation of range at http://documentcloud.github.com/underscore/#range.
I am not sure I understand your question correctly, but the following snippet might be what you are looking for.
var model = origColl.at(2);
var models = [model];
var newColl = new YourCollection(models);
newColl will now be a new collection containing the model at position 2 of your original collection. The example is a bit more verbose than I would write it, but it might make it clearer for you.

How can I access to some model in Backbone collection

I have a collection of models:
city = new M.City
App.citiesList = new C.CitiesList model: city
App.citiesList.fetch()
How can I access to the model with id=15 for example?
I need something like App.citiesList.find(15).name(), where name() is model function
When I try to add function find to the collection it is incorrect.
When I try to iterate over App.citiesList.models - I see only one model or what it is.. I actually don't know.
Thanks a lot!
If App.citiesList is a Backbone collection then you'd want to use get:
get collection.get(id)
Get a model from a collection, specified by id.
So this would get you your model from the collection:
fifteen = App.citiesList.get 15
And if you wanted to call a method on it:
App.citiesList.get(15).name()
You'd probably want to make sure you got something back from App.citiesList.get 15 first though (unless you knew it was there of course). Since you're working in CoffeeScript you could use the existence operator like this:
name = App.citiesList.get(15)?.name()
#----------------------------^
to get 15's name or undefined in the name variable.
The find method on App.citiesList would be Underscore's find and that doesn't find an object with a particular ID.

Resources