How to get models from a collection that have a certain attribute - backbone.js

I'd like to get some models in my collection that have the attribute unit. My current method involves this,
var unitIds = ciLocal.where({unit: !null});
console.log(unitIds.length);
The weird thing is that removing ! returns 58 (the total minus those that unit is not null) values while the code above returns 0.
Can anyone suggest a good way to loop my collection and return those models that have anything in unit?
Its probably worth mentioning that unit contains two values, one being unitID and the other being an array of more values. I need to get the whole model back and not just the unit section.
In this screenshot you can see that 68 has null while 69 has object.
{"carID":"37","unit":{"unitID":"37_Chaffinch_75","positionHistory":[{"lat":"51.474312","long":"-0.491672","time":"2011-07-08 11:24:47","status":"1","estimatedSpeed":"0","lastSoundFileName":"Car park Exit","lastSoundRange":"10","lastSoundTime":"2011-07-08 11:25:03","isToday":false,"minutesAgo":1028188}]},"registration":"CJ-361-YG","color":"Luxor","phone":"","model":"SDV8"}

You can use _.filter on your collection to specify a custom validation function.
filter _.filter(list, iterator, [context])
Looks through each value in the list, returning an array of all the values that pass
a truth test (iterator).
Something like this should keep the models with a defined, non null value
var c = new Backbone.Collection([
{id: 1, unit: 1},
{id: 2, unit: null},
{id: 3}
]);
c.filter(function(model) {
var v = model.get('unit');
return ((typeof(v)!=='undefined') && (v!==null));
})
And a demo http://jsfiddle.net/nikoshr/84L2R/

Related

SWIFT still fighting to assign a value to a nested array within a class

This carries on my last question struggling with value assignment to optional class variable, for which David provided me a good hint to a similar problem.
After numerous iterations I now came up with a different approach, however, it still fails and I have no idea why (and basically what happens)
I have the class definitions
struct HighScores: Codable {
var Scores:Int
var highscoreRecord: [HighscoreRecord]
}
struct HighscoreRecord: Codable {
var Rank:Int
var Date:String?
var avDuration:Float?
var Score:Int?
var Tries:Int?
}
In the view controller I have declared a variable of type HighScores, which may read the data from a JSON file or which may be initialized when setting the first high score.
class GameplayViewController: UIViewController {
var jsonResult: HighScores?
...
if firstHighscore == 1 {
jsonResult?.Scores = 1
jsonResult?.highscoreRecord.append(HighscoreRecord(Rank: 1, Date: formatter.string(from: dateStart), avDuration: Float(lblSpeed.text ?? "0.0"), Score: Int(lblRatio.text ?? "0"), Tries: hits + misses))
...
print(jsonResult)
This compiles and also runs. However, if I monitor the jsonResult variable, it still shows nil after assigning the Scores and and highscoreRecord values.
What happens, why can I assign a value without an error and without actually assigning it?
And first and foremost, how do I get my values into jsonResult?
Cheers
So following on from the comments above if you changed the code to be something along the lines of this you create the instance of the struct and add the values.
var jsonResult: HighScores?
if firstHighscore == 1 {
jsonResult = HighScores(Scores: 1, highscoreRecord: [HighscoreRecord(Rank: 1, Date: "your date", avDuration: 0.0, Score: 0, Tries: 0)])
}
once created you can add more highscorerecords to the array as needed, using the append method.

How to push object into an array? in Angular 7

I am pushing an object into an array but cannot do it?
I'm doing it like this
this.passData = this.tribeForm.value;
var id = {"tribe_id": 1}
this.passData.push(id)
This is the value in the tribeForm
I also tried
var id = {tribe_id: 1}
and
this.passData.splice(0,0, id)
and
this.passData = Array.prototype.slice(id)
and
this.passData.concat(id)
but it all ends up with
TypeError: this.passData.push/splice/concat is not a function
The question is not that clear, But I understood you are manipulating form data, value of form data returns an Object, Not an array. Objects in JavaScript are represented as key-value pairs, (or attribute-value) pairs.
Example :
var object = {
name : "Jhon",
grade : 12,
gpa : 8.12
}
It is just a collection of key-value pairs, push(), concat() and other methods are supported only for Arrays not for Objects. You can achieve whatever you want simply by creating a new key/attribute and assigning the value to it.
this.passData = this.tribeForm.value
this.passData['tribe_id'] = 1
//or, Objects can also contain nested object
this.passData['someKey'] = {'tribe_id' : 1}
You can create an empty array and push objects to it
Example :
var exampleArray = []
exampleArray.push({'tribe_id' : 1})
Now, it works because exampleArray is an Array not JS object.
Thanks for A2A
First, you need to understand the error:
TypeError: this.passData.push/splice/concat is not a function
Push/splice/concat is functions for Array and because of that the console is yelling at you that the passData is not an Array.
Make sure your passData is an Array and you will able to do so.

Javascript: array of objects VS object with unique properties?

I'm working in a real-time web application for my company, and I'm using MEAN stack with socket.io to provide real-time $scope variable updates in all clients in a specific socket room.
I'm currently using an array of objects that is dynamic, being able to add or remove elements, and I have to set a $watch function for each array element and pass the element's _id in it's respective $watch function. The problem is: AngularJS can't keep track of element's position in array by it's _id as elements are removed.
So I was considering, instead of using an array to store objects, use an object with unique properties that are each element's id, like this:
$scope.mainObj = {
'1234': {name: 'bob', age: 21},
'1235': {name: 'william', age: 23},
'1236': {name: 'rob', age: 28}
};
instead of:
$scope.mainArray = [
{_id: '1234', name: 'bob', age: 21},
{_id: '1235', name: 'william', age: 23},
{_id: '1236', name: 'rob', age: 28}
];
At first, I think this would remove the problem of having to index my array and having to locate the element's position in every client in a room to update a variable, making the changes atomic by updating the property named after element's _id.
Would this bring any performance issue or another problem? Like I said, array indexes would be dispensable, lookup functions to detect the element by _id wouldn't be necessary and the chances of updating the wrong element would be 0, as using the indexed array approach exists a minimal chance of the wrong element be updated when too many users are adding, removing or editing array elements.
So, is it a good idea? If not, how could I $watch array elements, pass the element _id in watch function and don't lose track of each element? What I have now is this:
$scope.setWatch = function (element, id) {
$scope.$watch(x, function() {
console.log('watching: ' + element);
console.log('do something with : ' + id);
});
}
socket.on('addArrayElm', function (res) {
var id = res.id;
$scope.mainArray.push(new arrayElement(id));//creates new element from constructor with received _id from server
$scope.mainArrayIndex.push(id);//push id in index array
var i = $scope.mainArrayIndex.length - 1;//get the pushed element index in array
var j = 'mainArrayIndex[' + i + '].name';//construct string to use in $watch function referring to the element in array's position 'i'
$scope.setWatch(j, z);
$scope.$apply();
});
The main problem is: if I remove an element, like the second one (index = 1), the $watch function is not destroyed, and as it took the index = 1 as a parameter, it's going to be triggered for the element that took index = 1, so the wrong _id is used.
What should I do?
Thanks!

Filter greater than and length angularjs

I need length of books that added after item, here is my controller:
$scope.items = [
{"added_days_ago": 5, "books": [{"id":1, "added_days_ago": 6}, {"id":2, "added_days_ago": 3}, {"id":3, "added_days_ago": 4}]},
{"added_days_ago": 2, "books": [{"id":4, "added_days_ago": 3}]}
]
In controller i need to define filteredBooksLength (i using ng-table) and then show like:
{{filteredBooksLength}}
Something like:
filteredBooksLength = (books where book.added_days_ago > item.added_days_ago).length
JSFiddle
$scope.filteredBooksLength = function (item) {
return item.books.filter(function (book) {
return book.added_days_ago > item.added_days_ago
}).length
Should cover your needs - summon it within the ng-repeat block, and pass in the current item - filteredBooksLength(item)
jsFiddle
How it works
We're giving the scope access to a function that accepts an item object as an argument. We take the books array on that object and pass it though a filter function, which returns only those books where book.added_days_ago is greater than item.added_days_ago as an array. We then measure the length of that array and return it.
Note on style
From what you've written - and the way you've phrased your question - it looks like you've done some Python. It's accepted practice in JS to use camelCase rather than snake_case - you may wish to change that for the the keys in your items object. In addition, the "" around those keys are superfluous.
Keep at it!

Backbone.js collection and sortedIndex always returning 0

I'm having trouble getting the sortedIndex underscore method to return a useful value. I have a collection with a comparator, and that's adding models correctly in order. I would just like to know the potential index of a new model, and the sortedIndex method is return 0 matter what I try.
var Chapter = Backbone.Model;
var chapters = new Backbone.Collection;
chapters.comparator = function(chapter) {
return chapter.get("page");
};
chapters.add(new Chapter({page: 9, title: "The End"}));
chapters.add(new Chapter({page: 5, title: "The Middle"}));
chapters.add(new Chapter({page: 1, title: "The Beginning"}));
var foo = new Chapter({ page: 3, title: 'Bar' });
// Will always return 0 no matter the value of page in foo.
console.log(chapters.sortedIndex(foo));
I know there's something wrong in there, or perhaps that's no the intention of sortedIndex but I'm unsure either way.
The problem is Underscore.js knows nothing about the comparator function of the collection and expects comparator as an argument of sortedIndex function. This will work as expected:
console.log(chapters.sortedIndex(foo, chapters.comparator));

Resources