Backbone: get model from collection - backbone.js

Im playing around with Backbone and are experiencing something I don't quite understand:
1) I have created some mock data in "data/applications.js"
[
{
"id": "1",
"title": "Title #1",
"image": "some/path1"
},
{
"id": "2",
"title": "Title #2",
"image": "some/path2"
},
{
"id": "3",
"title": "Title #3",
"image": "some/path4"
},
{
"id": "4",
"title": "Title #4",
"image": "some/path4"
}
]
2) Im trying to retrieve a single "application" in a collection
ApplicationModel = Backbone.Model.extend({});
ApplicationCollection = Backbone.Collection.extend({
url: "data/applications.json",
model: ApplicationModel
});
var applications = new ApplicationCollection();
applications.fetch();
var application = applications.get(applicationId); // I get this from route
console.log(applicationId); // returns 2
console.log(applications); // returns the collection with 4 models
console.log(application); // returns undefined
I have a feeling Im missing something?

When you fetch data with Backbone, it is done asynchronously, which means that your script continues to be executed while it is fetching. To retrieve your application, you have to wait for the fetch to end like that :
applications.fetch({success: function() {
console.log(applications.get(applicationId));
}});

Related

Dealing duplicate image data in React Native

I'm building 'Comments Detail page' which is a list view for comments in a single post (basically it's just facebook comments page).
I generated this JSON response data below, and as you can see, there are duplicate image urls. It means that if same user comments 100 times on a post, it needs to get image data from AWS 100 times rather than 1 time.
Maybe it's over-engineering? How do you guys deal with this?
Here is JSON data
{
"comments": [{
"id": 4,
"user": {
"image": "https://xxx.s3.amazonaws.com:443/-",
"id": 1,
"username": "jbaek73"
},
"content": "Edited!",
"publish": "2017-09-18T12:11:41.002838Z",
"updated": "2017-09-19T08:16:25.408756Z",
"reply_count": 1
},
{
"id": 13,
"user": {
"image": "https://xxx.s3.amazonaws.com:443/-",
"id": 1,
"username": "jbaek73"
},
"content": "Neaa!",
"publish": "2017-09-18T14:12:51.876523Z",
"updated": "2017-09-18T14:12:51.876600Z",
"reply_count": 0
},
{
"id": 14,
"user": {
"image": "https://xxx.s3.amazonaws.com:443/random",
"id": 5,
"username": "koreana"
},
"content": "Newa!",
"publish": "2017-09-19T08:16:35.190351Z",
"updated": "2017-09-19T08:16:35.190398Z",
"reply_count": 0
},
In this case, i would create an image object with all the required images and the user id as key:
randomFuntionName() { //you can call after you get your json
var img = []
comments.forEach((element) => { //comments are comming from your json btw
if (img[element.user.id] == null) {
img[element.user.id] = require(element.user.image)
}
})
this.setState({img})
}
render() {
//this part is only for example, you need to dynamicaly change userID
return (<Image source={this.state.img[userId]}/>)
}
This should do the work, but didn't tested it in app.

Add optgroups to angular-selectize asynchronously

I am using angular-selectize directive in my project. For this, I need to load optgroups asynchronously. So far I have tried multiple approaches but none of them works. The problem is, you cannot use the data returned by a promise synchronously. On the flip side, I have also been unable to initialize selectize from inside a promise callback. Given below is the code I currently have. Note that it is only to be used to get the idea of the data I'm playing with, not to present it as something you can consider right.
app.js
$http
.get('/get-categories')
.then(getCategoriesSCB, getCategoriesFCB);
function getCategoriesSCB(response) {
if(typeof(response.data) === 'object') {
posControl.menuCategories = response.data[0];
posControl.menuCategoryGroups = response.data[1];
}
else {
getCategoriesFCB(response);
}
}
function getCategoriesFCB(response) {
console.log(response);
}
posControl.menuConfig = {
valueField: 'id',
labelField: 'title',
placeholder: 'Select Category',
optgroupField: 'class',
optgroupLabelField: 'label',
optgroupValueField: 'value',
optgroups: posControl.menuCategoryGroups,
maxItems: 1,
searchField: ['title', 'category'],
onInitialize: function(selectize) {
console.log('selectize is here');
},
}
index.html
<selectize config="POSCtrl.menuConfig" options="POSCtrl.menuCategories" ng-model="POSCtrl.menuModel"></selectize>
data returned by ajax call
[
// this array has to be used for options.
[{
"class": "57b83830babb9",
"category": "Food Menu",
"id": "57b83855b23f9",
"title": "Beverages"
}, {
"class": "57b83830babb9",
"category": "Food Menu",
"id": "57b83855c05de",
"title": "Cuisines"
}, {
"class": "57b83830babb9",
"category": "Food Menu",
"id": "57b83855cdcb4",
"title": "Steaks"
}, {
"class": "57b83830d0899",
"category": "Wholesale Coffee",
"id": "57b83830d0899",
"title": "Wholesale Coffee"
}],
// this array has to be used for optgroups
[{
"value": "57b83830babb9",
"label": "Food Menu"
}, {
"value": "57b83830d0899",
"label": "Wholesale Coffee"
}]
]
You should be able to load a selectize asynchronously by setting the values directly on the posControl.menuConfig:
function getCategoriesSCB(response) {
if (typeof(response.data) === 'object') {
posControl.menuConfig.options = response.data[0];
posControl.menuConfig.optgroups = response.data[1];
}
}

How to insert array of document in mongodb using node.js?

I want to insert array of document to mongodb using node.js but while inserting it's only inserting first data only.
[{
"userid": "5664",
"name": "Zero 2679",
"number": "1234562679",
"status": "contact",
"currentUserid": "Abcd"
},
{
"userid": "5665",
"name": "Zero 3649",
"number": "1234563649",
"status": "contact",
"currentUserid": "Xyz"
}]
Sample code
collection.insert([{"userid": userid,"name": name,"number": number,"status": status,"currentUserid": currentUserid}], function(err, docs) {
if (err) {
res.json({error : "database error"});
}else {
collection.find({currentUserid:currentUserid}).toArray(function(err, users) {
res.send(users);
});
}});
But it still inserting first value only can you please tell me how to insert all these documents.
Please kindly go through my post and suggest me some solution.
In your sample code you are adding only 1 user.
db.collection('myCollection').insert([doc1, doc2]); inserts two documents using bulk write.
See documentation here: https://docs.mongodb.org/manual/reference/method/db.collection.insert/
From your sample, you can do:
var data = [{
"userid": "5664",
"name": "Zero 2679",
"number": "1234562679",
"status": "contact",
"currentUserid": "Abcd"
},
{
"userid": "5665",
"name": "Zero 3649",
"number": "1234563649",
"status": "contact",
"currentUserid": "Xyz"
}];
db.collection('myCollection').insert(data)
.then(function() {
return db.collection('myCollection').find({number: {$in: ["1234563649", "1234562679"]}});
})
.then(function(res) {
console.log(res);
});

Circular Reference - AngularJS/EF/WebAPI

I'm using AngularJS, EF and WebAPI. I have a one to many relationship between ObjectA and ObjectB.
In the UI, I want to loop through a list of ObjectA and do something like:
<table>
<tr ng-repeat="objectA in objectAs">
<td>objectA.objectB.Description</td>
<td>objectA.someValue</td>
</tr>
</table>
The problem is, if in my access layer, I do:
db.ObjectA.Include(o => o.ObjectB).ToList()
I get a nice error:
Object graph for type 'ObjectB' contains cycles and cannot be serialized if reference tracking is disabled.
Ok, no problem, I just add:
[DataContract(IsReference=true)]
to the *.tt file that generates the contracts (from EF).
WebAPI returns valid values (no error), but it looks like Angluar can't handle the "references" returned, which looks something like:
[
{
"$id": "1",
"someValue": "Pool",
"objectB": {
"$id": "2",
"Description": "Standard",
"ObjectAs": [
{
"$ref": "1"
},
{
"$id": "3",
"someValue": "Poolhouse",
"ObjectB": {
"$ref": "2"
},
},
},
{
"$ref": "3"
},
{
"$ref": "4"
},
{
"$ref": "5"
},
{
"$ref": "6"
},
{
"$ref": "7"
},
{
"$ref": "8"
},
{
"$ref": "9"
},
{
"$ref": "10"
},
{
"$ref": "11"
}
]
Now I can't really modify my DTOs to remove the DataMember attributes for certain navigation properties.
Any suggestions on best practices? Should I just return a light DTO (just object A), then have a javascript method that looks up Object B?
EDIT:
I took a look at the output from Angular. It turns out it converts the $ref props that WebAPI puts in to empty elements {}. Something like...
[
{
"$id": "1",
"someValue": "Pool",
"objectB": {
"$id": "2",
"Description": "Standard",
"ObjectAs": [
{
},
{
"$id": "3",
"someValue": "Poolhouse",
"ObjectB": {
},
},
},
{}, {},{}, {},{}, {},{}, {}
]
So from here, I see a few options:
Change code to only return a singluar object and make sep calls to get lookup fields
Set code to null out circular references:
ObjectA.objectB.ObjectAs = null;
Write my own formatter to handle the output
I would have expected this to be a common issue, but can't seem to find any posts about it. Is anyone else running into this?
I ended up add this to the WebApiConfig:
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None;
That produced "better" json from WebApi (no references)

Why is angularjs code slow?

Is it normal, that angularjs ng-repeat takes 1.5 Seconds to render data from an rest api? The result consists of only 10 rows with in total 1KB of data. How can I improve the speed or where to look for the problem?
ADDED INFOS:
The rest request itself only takes 128ms if I run it directly on the browser.
This is a set of sample data you get from the rest api:
{
"result": [
{
"id": 1224,
"name": "Schokolade-Vanille",
"kcal": 35500,
"displayName": "Schokolade-Vanille"
},
{
"id": 23423,
"name": "Naturreis Uncle Bens",
"kcal": 34400,
"displayName": "Naturreis Uncle Bens"
},
{
"id": 123231,
"name": "Paprikahendl",
"kcal": 4100,
"displayName": "Paprikahendl"
},
{
"id": 434,
"name": "Vanille Kugeln",
"kcal": 53700,
"displayName": "Vanille Kugeln"
},
{
"id": 323423,
"name": "Weihnachtstraum, Lindor-Kugeln",
"kcal": 60800,
"displayName": "Lindor-Kugeln"
},
{
"id": 5435,
"name": "Schokolade",
"kcal": 4300,
"displayName": "Schokolade"
},
{
"id": 23213,
"name": "Hühner-Nuggets",
"kcal": 23400,
"displayName": "Hühner-Nuggets"
},
{
"id": 5534,
"name": "Knödel, Kartoffel",
"kcal": 1230,
"displayName": "Knödel, Kartoffel"
},
{
"id": 23233,
"name": "Curvers",
"kcal": 15400,
"displayName": "Curvers"
},
{
"id": 53434,
"name": "Frites Original",
"kcal": 14100,
"displayName": "Frites Original"
}
],
"count": 12854
}
NEW ADDED INFOS
I have had a closer look now and found out, that not te repeat funktion is the problem.
I used the following code:
$scope.updateResultset = function() {
$scope.result = Food.query({
offset: $scope.offset,
order_by: $scope.orderby,
name: $scope.textfilter,
},function(){
console.log( "response " + (new Date().getTime() - start) );
});
$scope.offset = undefined;
console.log( "updateResultset " + (new Date().getTime() - start) );start = new Date().getTime();
And get the following response:
response 435
But the request itself only takes 131ms. In my opinion, >300ms is a lot of time to waste in a single method?
Compared to my former version, where I showed a plan html list, which was replaced by jquery ajax response html, its much slower?
As others indicated in the comments, the cause in the code is likely something else aside from ng-repeat. However, here are other options to consider, if speed still seems like an issue for ng-repeat:
quick-ng-repeat directive on github: https://github.com/allaud/quick-ng-repeat
ng-scroll, as part of angular-ui: https://github.com/angular-ui/ui-utils/blob/master/modules/scroll/README.md
Ok, I found out the problem. Not the repeatition of the 10 list items was the problem! As you can see in my question, I return not only the 10 results, but also the total amount of results. In my case it was '"count": 12854'.
On the same page, I have a pagination which was the part which slows down the whole page, since it had to render 1286 pager buttons (~12854/10). Now I only show 10 pager-buttons.

Resources