backbone js: collection event function options index undefined - backbone.js

I tried to get index value for the model. but its returning undefined value. how to get index value once an event is triggered.
var Test=new Backbone.Collection();
Test.add({name:'gowtham',age:20});
Test.add([{name:'eswara',age:25},
{name:'sakthi',age:20}]);
console.log(JSON.stringify(Test));
Test.remove(Test.at(1));
console.log(JSON.stringify(Test));
Test.on('add',function(model, col, options) {
console.log('added ' +model.get('name')+'at index '+ options.index);
});
Test.add({name:'ganesh',age:22});

In your example i do not see any try to output index of a model
Test.on('add',function(model, col, options) {
console.log('added ' +model.get('name')+'at index '+ `options.index);`
});
maybe its just a typo.
By default backbone add event callback has this three arguments: model, collection and options and there is no index, so you have to get it by yourself
I am putting here snippet about how to get index of added model
and how to add model at certain index
you still can check for additional information here: backbonejs.org
let test = new Backbone.Collection([{},{},{}]);
test.on('add', (model, collection) => {
console.log('index is: ', collection.indexOf(model))
});
let model1 = test.add({});
// console: index is: 3
test.add({}, { at:0 });
// console: index is: 0
console.log('model new index: ' + test.indexOf(model1))
// console: model new index: 4
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>

Related

How to fix 'TypeError: Cannot read property 'items' of undefined'

I am trying to display a reference field from my database as a result on my filtered repeater. I am unsure of how to code the page correctly for this to happen.
When testing my code, this is what shows in the developer console:
Loading the code for the SEARCH WITH VIN page. To debug this code, open i5zkm.js in Developer Tools.
Url: https://vpic.nhtsa.dot.gov/api/vehicles/decodevin/19UUA96299A543965/?format=jsonVINModule.jsw
Line 5{...}
SEARCH WITH VIN
Line 14{...}
VINModule.jsw
Line 12
Dataset is now filtered
SEARCH WITH VIN
Line 22
TypeError: Cannot read property 'items' of undefined
import {getVINInfo} from 'backend/VINModule';
import {wixData} from 'wix-data';
$w.onReady(function () {
//TO DO: Write Your Page Related Code Here:
});
export function button1_click(event, $w) {
//Add your code for this event here:
getVINInfo($w("#vininput").value)
.then(VINInfo => {
console.log(VINInfo)
$w("#results").text = VINInfo.Results[8].Value + " " + VINInfo.Results[5].Value + " " + VINInfo.Results[7].Value;
$w("#dataset1").setFilter(wixData.filter()
.eq("year", VINInfo.Results[8].Value)
.eq("make", VINInfo.Results[5].Value)
.eq("year", VINInfo.Results[7].Value))
.then((results) =>{
console.log("Dataset is now filtered");
$w("#repeater1").data = results.items;
let items = "title"
})
.catch((err) => {
console.log(err);
});
$w("#repeater1").expand();
})
}
I expect the repeater to show the title field from my database but nothing happens to the elements in the repeater and I receive the following in my developer console when previewing the page: TypeError: Cannot read property 'items' of undefined.
dataset setFilter() returns a promise with a void value, so you can't just access the dataset items from that returned promise.
If the repeater isn't already bound to the dataset, you should use getItems():
$w("#myDataset").getItems()
.then( (result) => {
$w("#repeater1").data = results.items
})

backbone fetch on a nested route

I have a Sitesand a Positionscollection. Each time the user selects a new site, the id is sent to the refreshPositions method which is in charge of doing the fetch call.
The route to get the positions look like this '.../sites/1/positions'
view.js
refreshPositions: function(siteId) {
this._positions.fetch({
success: this.onPositionsFetchSuccess.bind(this),
error: this.onPositionsFetchError.bind(this)
});
},
So refreshPositions is called whenever I need to update the positionson the page and the siteId parameter has the id, I just don't know to tell fetch to route to something like .../sites/n/positions where n would be the siteId .
Sorry if I missed relevant informations for my question, I'm pretty new to backbone.
I see, so you are calling fetch from your Positions Collection. The out-of-the-box functionality there is to fetch the whole collection (every Position object) if you have a RESTfull api set up. If you want more specific behaviour from your collection, you can probably write it into the Collection object definition.
var PositionCollection = Backbone.Collection.extend({
initialize: function(models, options) {
this.siteId = (options && options.siteId) || 0;
},
url: function() {
if (!this.siteId) {
return '/positions'; // or whatever
}
return '/sites/' + this.siteId + '/positions';
},
// etc...
});
Then, assuming that _positions refers to an instance of PositionCollection you can do:
refreshPositions: function(siteId) {
this._positions.siteId = siteId; // or wrap in a setter if you prefer
this._positions.fetch({
success: this.onPositionsFetchSuccess.bind(this),
error: this.onPositionsFetchError.bind(this)
});
},

Gathering a value from a column from each row from a table into an array in protractor

Writing e2e tests for an Angular App, but I don't seem to be able to get my head around async programming and promises.
I'm attempting to get the value from each row, from the first column and add that to an array to eventually sort it from high to low to have the highest value.
I'm having some trouble resolving the promise of my rows.each, the errormsg is:
'TypeError: undefined is not a function'
//This function will fetch the highest ID from the columns
this.getHighestScheduleId = (function(){
//Array to collect the ID's in
var idArray = [];
//Collects all the rows in our table
var rows = $$('#schedulesData');
//Goes through each row
rows.each(function(row){
//Collect all the row's elements in rowElems
var rowElems = row.$$('td');
console.log(rowElems[0].getText());
});
});
map() would fit nicely here:
rows.each(function(row) {
var rowElems = row.all('td').map(function (td) {
return td.getText();
});
// resolve the promise to see the output on the console
rowElems.then(function (values) {
console.log(values);
});
});

How to call fetch method of Backbone Collection passing Id

I want to fire fetch method on Backbone Collection which would pass an Id parameter similar to what happens in Model.fetch(id)
E.g.
var someFoo= new Foo({id: '1234'});// Where Foo is a Backbone Model
someFoo.fetch();
My Backbone collection:-
var tasks = backbone.Collection.extend({
model: taskModel,
url: '/MyController/GetTasks',
initialize: function () {
return this;
}
});
In my View when I try to fetch data:-
var _dummyId = 10; //
// Tried approach 1 && It calls an api without any `id` parameter, so I get 500 (Internal Server Error).
this.collection.fetch(_dummyId);
// Tried approach 2 && which fires API call passing Id, but just after that
// I am getting error as below:- Uncaught TypeError: object is not a function
this.collection.fetch({
data: {
id: _dummyId
}
});
Found it very late : To cut short the above story I want something like Get /collection/id in backbone.
Thank you for your answers, finally I got the solution from Backbone.js collection options.
Apologies that I couldn't explain the question properly while for same requirement others have done brilliantly and smartly.
Solution : I can have something like :-
var Messages = Backbone.Collection.extend({
initialize: function(models, options) {
this.id = options.id;
},
url: function() {
return '/messages/' + this.id;
},
model: Message,
});
var collection = new Messages([], { id: 2 });
collection.fetch();
Thanks to nrabinowitz. Link to the Answer
As mentioned by Matt Ball, the question doesn't make sense: either you call fetch() on a Collection to retrieve all the Models from the Server, or you call fetch() on a Model with an ID to retrieve only this one.
Now, if for some reason you'd need to pass extra parameters to a Collection.fetch() (such as paging information), you could always add a 'data' key in your options object, and it may happen that one of this key be an id (+add option to add this fetched model rather than replace the collection with just one model)... but that would be a very round-about way of fetching a model. The expected way is to create a new Model with the id and fetch it:
this.collection = new taskCollection();
newTask = this.collection.add({id: 15002});
newTask.fetch();
In your code however, I don't see where the ID is coming from, so I am wondering what did you expect to be in the 'ID' parameter that you wanted the collection.fetch() to send?

Returning values of a fetch

Please look at the code below. It's a Backbone/Parse code that uses some underscore features.
I'm trying to iterate over an Parse class to retrieve "firstName" attributes of all objects in that class.
I have 2 issues with it.
The first one, as indicated with the comment, is that it correctly retrieves the first names, but it duplicates them. So if there are 5 objects, it will retrieve 5 firstName * 5. There is an iteration problem here. This is shown with the console log.
Second problem, is that I try to push firstName values into an array, then return it, so I can use the values later in code using the testt variable. But checking the testt content with a console log sends a message instead of the firstname lists.
Do you see anyway how to fix this code ?
var DoopizCollection = Parse.Collection.extend({
model: Subscribers
}
);
var doopizlist = new DoopizCollection();
var testt;
testt = doopizlist.fetch({
success: function(doopizlist) {
var results = [];
doopizlist.each(function(object) {
results.push(doopizlist.pluck('firstName'));
console.log(doopizlist.pluck('firstName')); // logs 2 duplicate arrays
});
return results;
},
error: function(doopizlist, error) {
console.log("error"); // The collection could not be retrieved.
}
});
console.log(testt); // logs "a b.promise...." message instead of firstNames
The duplication issue is because you are looping over doopizlist twice, once with each and again with pluck. Pluck is just basically shorthand of the map method.
The second issue is, you are expecting testt is the resulting value, when actually it is an instance of jqXHR, which is something known as a promise. So you can use the then method to log the value of the result.
var DoopizCollection = Parse.Collection.extend({
model: Subscribers
}
);
var doopizlist = new DoopizCollection();
var testt;
testt = doopizlist.fetch({
success: function(results) {
return results.pluck('firstName');
},
error: function(results, error) {
console.log("error"); // The collection could not be retrieved.
}
});
testt.then(function(results) {
console.log(results);
});

Resources