How to order a dictionary by value in AngularJS - angularjs

I've a REST api that returns the list of locales as dictionary:
{
"en-uk": "English UK",
"en-us": "English USA",
...
}
This dictionary is correctly ordered alphabetically by value.
When AngularJS receives it via HTTP, the dictionary gets automatically re-sorted by key, so when I bind to a select element the list of options is ordered by key, and the alphabetical order by key doesn't match the one by value, I get a wrong sorting.
The problem I suppose is due to the fact that such dictionary becomes basically one object with 800+ properties. How do I sort it by value?

First: You have to find all keys.
Second: Iterate all the keys.
Third: Then sort the array with values.
Please use the following:
let obj = {
"en-us": "English USA",
"en-uk": "English UK"
};
// Get an array of the keys:
let keys = Object.keys(obj);
// Then sort by using the keys to lookup the values in the original object:
keys.sort(function(a, b) { return obj[a] > obj[b] });
console.log(keys);
console.log(obj[keys[0]]);

You can modify the way you send the response from the server. Instead of sending the response as an object, send the stringified object.

The problem is indeed you cannot sort the values of the properties of an object. So I convert it to an array before binding it:
So,
languageResource.getCultures().then(function(cultures) {
vm.availableCultures = cultures;
});
becomes
languageResource.getCultures().then(function (culturesDictionary) {
var cultures = [];
angular.forEach(culturesDictionary, function (value, key) {
cultures.push({
lcid: key,
name: value
});
});
vm.availableCultures = cultures;
});

Seen this when the key is numerical. If the key's data type is string than it would keep its sorted state after an API call. If the key's data type is numerical, than, you would need set the key's value as a string and even add single quotes before and after the key's value, before the API sends it back.
I haven't tried the approach to stringfy the dictionary in the API. After the call you would parse the string back to an object with something like JSON.parse(string) might be your best bet.

Related

de-duping items in a mongoose list of populate IDs

I have a mongoose object which contains an array of ObjectIds, being used for population from another table. I want to be able to dedupe these. eg I have
[ '61e34f3293d9361bbb5883c7' ,'61e34f3293d9361bbb5883c7', '61e34f3293d9361bbb5883c7' ]
When i print and iterate through these they look like strings.
But they also have an _id property, so I think they're somehow "populated" or at least contain references to the child table.
What's the best way to do this? I tried:
const uniqueTokens = _.uniqBy(tokens, '_id') which doesn't seem to work as _id is some kind of Object.
converting to a string will allow me to dedupe:
const tokens = this.tokens || []
let newTokens: string[] = []
for (let t of tokens) {
const text = t.toString()
// clog.info('t', t, t._id, typeof t._id)
if (!newTokens.includes(text)) {
newTokens.push(text)
}
}
but then these aren't real Objects I can assign back to the original parent object.
// this.tokens = newTokens
await this.save()
I could maybe go through and re-find the objects, but that seems to be digging deeper into the hole!
Seems there must be a better way to handle these type of types...
related searches
How to compare mongoDB ObjectIds & remove duplicates in an array of documents using node.js?
I also tried using lean() on the tokens array to try and convert it back to a simple list of references, in case somehow the 'population' could be undone to help.
I'm down to creating a unique signature field for the referenced items and de-duping based on that.

How do we compare the value in RealmSwift List and Json nested Array?

Realmswift Data Model
class User {
let id = RealmOptional<Int>()
dynamic var name = ""
let albums = List<Album>()
override static func primaryKey() -> String {
return "id"
}
}
class Album: Object {
dynamic albumName = ""
let imageIDs = List<ImageID>()
}
class ImageID: Object {
let imageId = RealmOptional<Int>()
}
JSON data
{
"10001": {
"id" : 10001,
"name": "John",
"album": {
"albums": [
{
"albumName": "Summer1999",
"imageIds": [11223, 11224, 11227]
},
{
"albumName": "Xmas1999",
"imageIds": [22991, 22997]
},
{
"albumName": "NewYear2000",
"imageIds": [5556, 776, 83224, 87543]
}
]
}
}
}
I have the above json data and I m using SwiftyJSON to parse the data then write into realm. Everything is working great except for checking and updating of data (for example imageIds on json file have changed).
Question: How do i compare the JSON arrays and RealmSwift List to determine it any updates need to be written into the database?
You can take advantage of your primary key here. As Realm Swift documentation states:
Creating and Updating Objects With Primary Keys: If your model class
includes a primary key, you can have Realm intelligently update or add
objects based off of their primary key values using
Realm().add(_:update:).
So (I assume that you get the JSON from some kind of a request (REST etc.) and then parse it with SwiftyJSON to create a 'User' object) you can treat the new 'User' object as regular new 'User' and try to add it to Realm as usual, but 'update' parameter must be 'true'. If there already was a user with the id of the 'User' object you are trying to add, it will just update the existing 'User' i.e. changing its modified values from the new 'User' created by parsing new JSON data. This might look something like this:
//Parse JSON and create a 'User'
let newUserFromJSON = parseAndCreateUserFromJSON(JSONData)
let realm = try! Realm()
do {
try realm.write {
realm.add(newUserFromJSON, update: true)
}
} catch let error as NSError {
print("error writing to realm: \(error.description) & \(error)")
} catch {
print("error writing to realm: UNKNOWN ERROR")
}
I'm afraid there's probably no easy answer to this. There's no mechanism in Realm to compare the contents of a Realm Object to an external object to see if their data matches. You would need to iterate through each object in the Realm object and manually compare it.
This wouldn't be too much code to write (Since you can get a list of all of the Realm file's properties via the objectSchema property of Realm objects, and then use key-value coding to pull them out in a single for loop), but would still be a fair amount of overhead to perform the compare.
That being said, if what you're wanting to look at is just certain properties that might change (i.e. like you said, just the imageIDs property), then you could easily just check the values you need.
What bcamur has suggested is definitely the quickest (And usually preferred for JSON handing) solution here. As long as you've set your primary key properly, you can call Realm.add(_:, update:) with update set to true to update the object.
Please keep in mind this doesn't merge the new data with what was already in Realm; it'll completely overwrite the old object with the new values, which if it sounds like your ID numbers are changing, would be the best course of action.

Can I check if a value is only pushed if a certain field value is not filled already?

I am trying to make a Meteor app to let users push a value to the database. It works ok, but there a small issue. As soon a certain user has pushed his information, i don't want to let the same user create another entry. Or this must be blocked, or the value the user is pushing must be overwritten for the value he is posting the second time. Now I get multiple entry's of the same user.
Here is my code. Hope you can help me here. Thanks in advance.
Estimations.update(userstory._id, {
$addToSet: {
estimations: [
{name: Meteor.user().username, estimation: this.value}
]
}
});
From the mongo docs
The $addToSet operator adds a value to an array unless the value is
already present, in which case $addToSet does nothing to that array.
Since your array elements are objects the value is the entire object, not just the username key. This means a single user can create multiple name, estimation pairs as long as the estimation value is different.
What you can do is remove any value for the user first, then reinsert:
var username = Meteor.user().username;
Estimations.update({ userstory._id },
{ $pull: { estimations: { name: username }}}); // if it doesn't exist this will no-op
Estimations.update({userstory._id },
{ $push: { estimations: { name: username, estimation: this.value }}});
By way of commentary, you've got a collection called Estimations that contains an array called estimations that contains objects with keys estimation. This might confuse future developers on the project ;) Also if your Estimations collection is 1:1 with UserStorys then perhaps the array could just be a key inside the UserStory document?

How to add new items to an array in MongoDB

I'm trying to add a new item to whichever name that was passed in under whichever id. My first problem is that it seems like its not grabbing the values from any of my variables (name, item, id), instead just using them as object keys. My next issue is that when I tested by hard-coding sample table info onto here, it wasn't adding more items to that array, but simply replacing the entire array with whatever values I had here.
function addlist(name, item, id){ // Add to user's list
console.log(id);
db.collection('newcon').update({_id: id}, { "$set": { "$push": { name:item } } });
ret(id);
}
$set is not an array update operation.
The $set operator replaces the value of a field with the specified value.
You just want to use $push by itself, as in
.update({_id: id}, {$push: {name: item}})
You can't interpolate object property names in raw object declarations, so if you want to use a variable name you will have to create an object to do this:
var obj = {};
obj[name] = item;
You can then pass this to .update, {$push: obj}

How do i get the specific value from json data using Angularjs

i am new to AngularJs. I am trying to get the values from json based on search key word and displaying that related data.
Below is my json format
{"abc":[
{ "url":"abc.json"}
],
"bbc":[
{"url":"bbc.json"}
]
}
i am comparing the key with entered search word. If it matches then i need to load the separate json which is related to found key. I am able to compare the search word with key, but when i am trying to get the value am getting total value like url=abc.json, instead of this i've to get only abc.json. My controller code is as follows
function getDetailsController($scope,$http) {
$scope.search = function() {
$http.get("searchInfo.json").success(function(response) {
angular.forEach(response, function(value, key) {
if(angular.equals(key, $scope.searchText)){
$scope.url = value;
$http.get(url).success(function(response) {
$scope.details = response;
});
}
});
});
};
}
I have tried in diffrent ways but i was not able to get the value. Could you please help me on this.
In your JSON, '"abc"': is a key, and its corresponding value is
[{ "url":"abc.json"}]
That is an array containing a single object, the object containing a single key: "url".
So, to access this URL, you simply need
value[0].url
This structure is quite strange though. I don't really understand the point of wrapping the object inside an array.

Resources