ng-repeat with variabile as something - angularjs

Let's imagine I have an array I want to iterate. So standard way I would just
<div ng-repeat=obj in arr>
Which works correctly ofc. But let's also imagine situation i will work whole time just with obj property data.
So for example:
<span>{{obj.data.firstName}}</span>
<span>{{obj.data.lastName}}</span>
It works but it start looking ugly, and just in case it will have one aditional subobject or array it can go even worser.
So I hope if there is something like:
<div ng-repeat=obj.data as o in arr>
I didnt find any information about it in Angular Doc but I belieave it could be possible or atleast work arounded.
Any idea?
EDIT:
e.g. array:
[{
"data": {
"Name": "MyName",
"Gender": "female"
},
"data2": {
"nothing": true
}
}, {
"data": {
"Name": "MyNam2e",
"Gender": "male"
},
"data2": {
"nothing": true
}
}]

Related

Query an array of users based on an array of users

Basically I'm having trouble understanding how I would figure this out.
I have a document in a mongodb collection, and that document has field called friends which is an array of usernames.
I want to query through each username in the array friends, and have an array of those user documents. I'm terrible at explaining maybe if I draw this out it'll make sense.
mongodb document:
{
"_id": {
"$oid": "59a20e65f94cb5e924af774e"
},
"name": "Nick",
"friends": ["Jones","Mark","Mike"]
}
Now with this friends array, I want to search the same collection for an object with the "name" Jones, Mark, and Mike. When I find that object, I want to put it into an array.
Basically I want it to return this, (for this example let's say Jones, Mark, and Mike only have one friend, and that friend is Nick.
[{
"_id": {
"$oid": "59a20e65f94cb5e924af774e"
},
"name": "Jones",
"friends": ["Nick"]
},
{
"_id": {
"$oid": "59a20e65f94cb5e924af774e"
},
"name": "Mark",
"friends": ["Nick"]
},
{
"_id": {
"$oid": "59a20e65f94cb5e924af774e"
},
"name": "Mike",
"friends": ["Nick"]
}]
^ an array of three objects, which are all the friends of Nick.
If you need any more explanation please let me know, I'm terrible at this type of stuff.
For the record, I'm using node, and basic mongodb (not mongoose).
I believe you are looking for $in operator.
// doc.friends = ["Jones","Mark","Mike"]
db.collection.find({ name: { $in: doc.friends }})

Multiple search filtering is not working in cloudant, why?

Here i quoted my code for multiple search filtering. I could not find the mistakes in that. please give a right code to make it work well.
Employee document:
{
"_id": "527c8d9327c6f27f17df0d2e17000530",
"_rev": "24-276a8dc913559901897fd601d2f9654f",
"proj_role": "TeamMember",
"work_total_experience": "3",
"personal": {
"languages_known": [
"English","Telugu"
]},
"skills": [
{
"skill_set": "Webservices Framework",
"skill_exp": 1,
"skill_certified": "yes",
"skill_rating": 3,
},
{
"skill_set": "Microsoft",
"skill_exp": 1,
"skill_certified": "yes",
"skill_rating": 3,
}
]
"framework_competency": "Nasscom",
"type": "employee-docs"
}
Design Document:
{
"_id": "_design/sample",
"_rev": "86-1250f792e6e84f6f33447a00cf64d61d",
"views": {},
"language": "javascript",
"indexes": {
"search": {
"index": "function(doc){\n index(\"default\", doc._id);if(doc.type=='employee-docs'){\nif (doc.proj_role){index(\"project_role\", doc.proj_role);}if(doc.work_total_experience){\nindex(\"work_experience\", doc.work_total_experience);}\nif(doc.personal.languages_known){for(c in doc.personal.languages_known){ \n index(\"languages_known\",doc.personal.languages_known[c]);}} if(doc.skills){for (var i=0;i<doc.skills.length;i++){\nindex('skill_set',doc.skills[i].skill_set);}}}}"
}
}
}
Run using below URL : https://ideyeah4.cloudant.com/opteamize_new/_design/sample/_search/search?q=project_role:TeamMember%20AND%20work_experience:%223%22%20AND%20languages_known:Telugu%20AND%20skill_set:Microsoft&include_docs=true
A simple way to debug this is to query the top 100 results in your index:
https://ideyeah4.cloudant.com/opteamize_new/_design/sample/_search/search?q=*:*&limit=100
This will at least tell you whether there are any documents in your index at all.
Your current query (without URL encoding) looks like:
project_role:TeamMember AND work_experience:"3" AND languages_known:Telugu AND skill_set:Microsoft
I'd suggest that some of these search values require quotes - always true when you are searching string values. Next, you could try:
project_role:"TeamMember"
see if you get any results and refine from there.
Debugging this might also be easier if you store the values as well as index them (so you can see exactly what is indexed). To do this, add an object to each index call { "store": true }. For example,
index("languages_known", doc.personal.languages_known[c], { "store": true });
Now, when you query the index it will return a list of fields which were stored with each match.

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)

MongoDB Array Query Performance

I'm trying to figure out what the best schema is for a dating site like app. User's have a listing (possibly many) and they can view other user listings to 'like' and 'dislike' them.
Currently i'm just storing the other persons listing id in a likedBy and dislikedBy array. When a user 'likes' a listing, it puts their listing id into the 'liked' listings arrays. However I would now like to track the timestamp that a user likes a listing. This would be used for a user's 'history list' or for data analysis.
I would need to do two separate queries:
find all active listings that this user has not liked or disliked before
and for a user's history of 'liked'/'disliked' choices
find all the listings user X has liked in chronological order
My current schema is:
listings
_id: 'sdf3f'
likedBy: ['12ac', 'as3vd', 'sadf3']
dislikedBy: ['asdf', 'sdsdf', 'asdfas']
active: bool
Could I do something like this?
listings
_id: 'sdf3f'
likedBy: [{'12ac', date: Date}, {'ds3d', date: Date}]
dislikedBy: [{'s12ac', date: Date}, {'6fs3d', date: Date}]
active: bool
I was also thinking of making a new collection for choices.
choices
Id
userId // id of current user making the choice
userlistId // listing of the user making the choice
listingChoseId // the listing they chose yes/no
type
date
I'm not sure of the performance implications of having these choices in another collection when doing the find all active listings that this user has not liked or disliked before.
Any insight would be greatly appreciated!
Well you obviously thought it was a good idea to have these embedded in the "listings" documents so your additional usage patterns to the cases presented here worked properly. With that in mind there is no reason to throw that away.
To clarify though, the structure you seem to want is something like this:
{
"_id": "sdf3f",
"likedBy": [
{ "userId": "12ac", "date": ISODate("2014-04-09T07:30:47.091Z") },
{ "userId": "as3vd", "date": ISODate("2014-04-09T07:30:47.091Z") },
{ "userId": "sadf3", "date": ISODate("2014-04-09T07:30:47.091Z") }
],
"dislikedBy": [
{ "userId": "asdf", "date": ISODate("2014-04-09T07:30:47.091Z") },
{ "userId": "sdsdf", "date": ISODate("2014-04-09T07:30:47.091Z") },
{ "userId": "asdfas", "date": ISODate("2014-04-09T07:30:47.091Z") }
],
"active": true
}
Which is all well and fine except that there is one catch. Because you have this content in two array fields you would not be able to create an index over both of those fields. That is a restriction where only one array type of field (or multikey) can be be included within a compound index.
So to solve the obvious problem with your first query not being able to use an index, you would structure like this instead:
{
"_id": "sdf3f",
"votes": [
{
"userId": "12ac",
"type": "like",
"date": ISODate("2014-04-09T07:30:47.091Z")
},
{
"userId": "as3vd",
"type": "like",
"date": ISODate("2014-04-09T07:30:47.091Z")
},
{
"userId": "sadf3",
"type": "like",
"date": ISODate("2014-04-09T07:30:47.091Z")
},
{
"userId": "asdf",
"type": "dislike",
"date": ISODate("2014-04-09T07:30:47.091Z")
},
{
"userId": "sdsdf",
"type": "dislike",
"date": ISODate("2014-04-09T07:30:47.091Z")
},
{
"userId": "asdfas",
"type": "dislike",
"date": ISODate("2014-04-09T07:30:47.091Z")
}
],
"active": true
}
This allows an index that covers this form:
db.post.ensureIndex({
"active": 1,
"votes.userId": 1,
"votes.date": 1,
"votes.type": 1
})
Actually you will probably want a few indexes to suit your usage patterns, but the point is now can have indexes you can use.
Covering the first case you have this form of query:
db.post.find({ "active": true, "votes.userId": { "$ne": "12ac" } })
That makes sense considering that you clearly are not going to have both an like and dislike option for each user. By the order of that index, at least active can be used to filter because your negating condition needs to scan everything else. No way around that with any structure.
For the other case you probably want the userId to be in an index before the date and as the first element. Then your query is quite simple:
db.post.find({ "votes.userId": "12ac" })
.sort({ "votes.userId": 1, "votes.date": 1 })
But you may be wondering that you suddenly lost something in that getting the count of "likes" and "dislikes" was as easy as testing the size of the array before, but now it's a little different. Not a problem that cannot be solved using aggregate:
db.post.aggregate([
{ "$unwind": "$votes" },
{ "$group": {
"_id": {
"_id": "$_id",
"active": "$active"
},
"likes": { "$sum": { "$cond": [
{ "$eq": [ "$votes.type", "like" ] },
1,
0
]}},
"dislikes": { "$sum": { "$cond": [
{ "$eq": [ "$votes.type", "dislike" ] },
1,
0
]}}
])
So whatever your actual usage form you can store any important parts of the document to keep in the grouping _id and then evaluate the count of "likes" and "dislikes" in an easy manner.
You may also not that changing an entry from like to dislike can also be done in a single atomic update.
There is much more you can do, but I would prefer this structure for the reasons as given.

AngularJs - Filtering out duplicates in select control

I have a select list of axleTypes, each having a Type property of either a Front Axle or a Rear Axle. I can not seem to filter out duplicate words of 'Front' and 'Rear'.
Update:
Html:
<select ng-model="axleType.Type" ng-options="type for type in uniqueTypes">
Controller:
$scope.axleTypes = API.GetAxleTypes();
$scope.fixedAxleTypes = [
{ "$id": "1", "Description": "I beam, telescopic type shock absorbers", "Type": "Front", "Id": 1 },
{ "$id": "2", "Description": "Full-floating banjo housing", "Type": "Rear", "Id": 2 },
{ "$id": "3", "Description": "Something Else", "Type": "Rear", "Id": 2 },
{ "$id": "4", "Description": "I beam, telescopic type shock absorbers", "Type": "Front", "Id": 4 }
];
// This Works
$scope.uniqueTypes = _.uniq(_.pluck($scope.fixedAxleTypes, 'Type'));
// This does not
//$scope.uniqueTypes = _.uniq(_.pluck($scope.axleTypes, 'Type'));
// This does not
//$scope.uniqueTypes = _.uniq(_.pluck(API.GetAxleTypes(), 'Type'));
I am thoroughly confused. And yes, the API works, I copy pasted above data from
Chrome > Network>Response window
Seeing the error that you added in your edit, I'm sure that the reason is what I described in my comment, which is the use of the (axleType.Type) expression for the filter in a context where that expression cannot be evaluated. Since you're not using the expression in the filter implementation, you could just omit it altogether, I believe.
What i guess is API.GetAxleTypes(); should be doing some asynch tasks like calling $http.
if that is the case then $scope.axleTypes wont be of the array type you are looking for.
The the GetAxleTypes can look something similar to this.
Service definition:
{
uniqueaxleTypes:[],
GetAxleTypes = function($http,..){
var promise = $http({
//config
})
promise.then(function(response){
this.uniqueaxleTypes = _.uniq(_.pluck(response.data, 'Type'));
})
}
}
Then if you bind a scope variable to this uniqueaxleTypes it will always reflect the unique values.
Since $scope.fixedAxleTypes is a hard coded value, its working fine.

Resources