Lodash: convert array to angularjs nvd3 Multibarchart data - angularjs

i want to convert my apiArray fetched from api to AngularJS NVD3 MultiBarChart data format.
$scope.apiArray = [{"date":"2018-07-05T05:05:39.732Z","id":2"count":1},{"date":"2018-07-05T05:05:39.732Z","id": 3,"count": 1},"date": "2018-07-06T05:05:39.732Z","id": 2,"count": 1}, {"date": "2018-07-06T05:05:39.732Z","id": 4,"count": 2}
Using Lodash library where key is my id, to ->
$scope.data = [{"key":"2", "values":[{"date": "2018-07-05T05:05:39.732Z", "count": "1"},{"date": "2018-07-06T05:05:39.732Z", "count": "1"}]},{"key":"3", "values":[{"date": "2018-07-05T05:05:39.732Z", "count": "1"}]},{"key":"4", "values":[{"date": "2018-07-06T05:05:39.732Z", "count": "2"}]}]
Is there any solution? I want to feed my apiArray to AngularJS NVD3 to create Multibar chart.

you can simply use a _.groupBy with a _.map to acheive this
_(data).groupBy('id').map((values, key) => ({key, values})).value()
First grouped by the 'id', it will return a object where keys will
be unique ids and each values will a array contains all the objects
having that id
Then map it (each key/value) to a object have key key and values,
key will contain the unique id and values will be the objects having
that id (what we get in _.groupBy against each unique id, simple use that)
var data = [{ "date": "2018-07-05T05:05:39.732Z", "id": 2, "count": 1 }, { "date": "2018-07-05T05:05:39.732Z", "id": 3, "count": 1, }, { "date": "2018-07-06T05:05:39.732Z", "id": 2, "count": 1 }, { "date": "2018-07-06T05:05:39.732Z", "id": 4, "count": 2 } ];
var res = _(data)
.groupBy('id')
.map((values, key) => ({ key, values}))
.value();
console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

This should help you:
var data = [{ "date": "2018-07-05T05:05:39.732Z", "id": 2, "count": 1 }, { "date": "2018-07-05T05:05:39.732Z", "id": 3, "count": 1, }, { "date": "2018-07-06T05:05:39.732Z", "id": 2, "count": 1 }, { "date": "2018-07-06T05:05:39.732Z", "id": 4, "count": 2 } ]
const result = _(data)
.groupBy(x => x.id)
.entries()
.map(x => ({ key: x[0], values: x[1]}))
.value()
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
We are using chaining then grouping by (via groupBy) the id, then using entries to get the contents in an array form and then just map to the expected object result.

Related

How filter and delete object with null or empty property in json query

I have this json :
{
"meta": {
"status": 200,
"pagination": {
"page": 1,
"perPage": 15,
"hasNext": true
}
},
"data": [
{
"id": "1",
"title": "Movie title1"
"rating": null,
"playProviders": [
]
},
{
"id": "2",
"title": "Movie title2"
"rating": {
"ratingAssessment": "7.1"
},
"playProviders": [
"HBO", "Netflix"
]
},
....
}
I want to create a page with a list of movies, I need to fetch movies but only those which have a rating and playProviders, what parameters should I use in this request?
https://api.com/movies?orderBy=views
When I filters in the code:
programs.filter((program) => program.rating !== null);
it only gets a few films per page, those that don't have null. For example, 15 are per page and I get 2. How do I filter this? (I am using react typescript)
I don't have access to the API code. I need to filter what is returned by the API or write a query so that you get already filtered data from the API.
programs = [
{rating: 1,
playProviders: ["sf"]
},
{
rating: 4,
playProviders: []
}
]
programs.filter(function(program) {
if (program.rating !== null && program.playProviders.length !== 0) {
return program;
}
})

How to set unique constraint for field in document nested in array?

I have a collection of documents in MongoDB that looks like:
{"_id": 1, "array": [{"id": 1, "content": "..."}, {"id": 2, "content": "..."}]}
{"_id": 2, "array": [{"id": 1, "content": "..."}, {"id": 2, "content": "..."}, {"a_id": 3, "content": "..."}]}
and I want to ensure that there is no duplicate array.id within each document. So the provided example is ok, but the followign is not:
{"_id": 1, "array": [{"id": 1, "content": "..."}, {"id": 1, "content": "..."}]}
My question is how to do this (preferably in PyMongo).
EDIT
What I tried was the following code that I thought would create key on (_id, array.id) but if you run it this does not happen:
from pymongo import MongoClient, ASCENDING
client = MongoClient(host="localhost", port=27017)
database = client["test_db"]
collection = database["test_collection"]
collection.drop()
collection.create_index(keys=[("_id", ASCENDING),
("array.id", ASCENDING)],
unique=True,
name="new_key")
document = {"array": [{"id": 1}, {"id": 2}]}
collection.insert_one(document)
collection.find_one_and_update({"_id": document["_id"]},
{"$push": {"array": {"id": 1}}})
updated_document = collection.find_one({"_id": document["_id"]})
print(updated_document)
which outputs (note that there are two objects with id = 1 in the array). I would expect to get an exception.
{'_id': ObjectId('5eb51270d6d70fbba739e3b2'), 'array': [{'id': 1}, {'id': 2}, {'id': 1}]}
So if I understand it correctly there is no way how to set index (or
some condition) that would enforce the uniqueness within the document,
right? (Other than check this explicitly when creating the document or
when inserting into it.)
Yes. Please see the following two scenarios about using the unique index on an array field with embedded documents.
Unique Multikey Index (index on embdeed document field within an array):
For unique indexes, the unique constraint applies across separate
documents in the collection rather than within a single document.
Because the unique constraint applies to separate documents, for a
unique multikey index, a document may have array elements that result
in repeating index key values as long as the index key values for that
document do not duplicate those of another document.
First Scenario:
db.arrays.createIndex( { _id: 1, "array.id": 1}, { unique: true } )
db.arrays.insertOne( { "_id": 1, "array": [ { "id": 1, "content": "11"}, { "id": 2, "content": "22"} ] } )
db.arrays.insertOne( { "_id": 2, "array": [ { "id": 1, "content": "1100"}, { "id": 5, "content": "55"} ] } )
db.arrays.insertOne( {"_id": 3, "array": [ {"id": 3, "content": "33"}, {"id": 3, "content": "3300"} ] } )
All the three documents gets inserted without any errors.
As per the note on Unique Multikey Index, above, the document with _id : 3 has two embedded documents within the array with same "array.id"value: 3.
Also, the uniqueness is enforced on two keys of the compound index { _id: 1, "array.id": 1} and there were duplicate "array.id" values across the documents also ( the _id values 1 and 2).
Second Scenario:
db.arrays2.createIndex( { "array.id": 1 }, { unique: true } )
db.arrays2.insertOne( { "_id": 3, "array": [ { "id": 3, "content": "33" }, { "id": 3, "content": "330"} ] } )
db.arrays2.insertOne( { "_id": 4, "array": [ { "id": 3, "content": "331" }, { "id": 30, "content": "3300" } ] } )
The first document with _id : 3 gets inserted successfully. The second one has an error: "errmsg" : "E11000 duplicate key error collection: test.arrays2 index: array.id_1 dup key: { array.id: 3.0 } ". This behavior is as expected as per the note Unique Multikey Index.
You can do this check on update
const doc = await Model.findOneAndUpdate(
{ _id, 'array.id': { $ne: newID} },
{
$push: {
array: newID
}
},
{ new: true }
);

How to print only first element from JSON Array in ReactJs?

I have the following JSON Array data from which I want to print Charlie. How to do it?
[ [ {
"ID": 1,
"Name" :"David"
},{
"ID": 2,
"Name" :"Antony"
}],[{
"ID": 1,
"Name" :"Bob"
},{
"ID": 2,
"Name" :"Charlie"
} ] ]
you are using {PostData.map((group, index)=>{ return <p>{group.Name}</p>, since you are using map here PostData[0].Name will throw error inside map(), because you are iterating array with map().
Since you only need first item, you can simply use <p>PostData[0].Name</p>
var data = [{
"ID": 1,
"Name" :"David",
}, {
"ID": 2,
"Name" :"Antony",
}];
console.log(data[0].Name)
var response= [{
"ID": 1,
"Name" :"David",
}, {
"ID": 2,
"Name" :"Antony",
}];
console.log(response[0].Name) will give you first element of Array and return data with Key 'Name'.

How to Join Multiple Arrays inside filter function of Arrays in Typescript

I am using Typescript in an Angular/Ionic project. I have an array of users that contain an array of skills. I have to filter users based on their online status as well as skills.
[
{
"id": 1,
"name": "Vikram Shah",
"online_status": "Online",
"skills": [{
"id": 2,
"title": "CSS"
},
{
"id": 3,
"title": "JavaScript"
},
{
"id": 4,
"title": "Python"
}
]
},
{
"id": 1,
"name": "Abhay Singh",
"online_status": "Online",
"skills": [{
"id": 1,
"title": "HTML"
},
{
"id": 2,
"title": "CSS"
},
{
"id": 3,
"title": "JavaScript"
},
{
"id": 4,
"title": "Python"
}
]
},
{
"id": 1,
"name": "Test Oberoi",
"online_status": "Online",
"skills": [{
"id": 1,
"title": "HTML"
},
{
"id": 2,
"title": "CSS"
},
{
"id": 3,
"title": "JavaScript"
},
{
"id": 4,
"title": "Python"
}
]
}
]
This is how all skills look like
this.skill_types = [
{"id":8,"title":"Cleaner", checked:false},
{"id":7,"title":"Painter", checked:false},
{"id":6,"title":"Plumber", checked:false},
{"id":5,"title":"Carpenter", checked:false},
{"id":4,"title":"Advisor", checked:false},
{"id":3,"title":"Team Leader", checked:false},
{"id":2,"title":"Management", checked:false},
{"id":1,"title":"Administrator", checked:false}
];
This array contains the IDs of skills that I want to filter
filterArr = [1, 3, 6];
This solution is almost working as expected. It is filtering well based on two criteria together.But not sure how to add condition for second filtering. The second filter should apply only if filterArr is not empty.
return this.items = this.items.filter((thisUser) => {
return thisUser.online_status.toLowerCase().indexOf(onlineStatus.toLowerCase()) > -1 &&
thisUser.skills.some(c => this.filterArr.includes(c.id))
});
The issue I am facing with code above is When there is no skill selected in the filter criteria, I would like to display all users. But it is not working that way. The logic here is to not apply any filter when the size of selected skills (filter condition) is greater than zero. So I tried this way....which looks similar to the way above...but this makes everything worse.
let filteredByStatus = [];
filteredByStatus = this.items.filter((thisUser) => {
return thisUser.online_status.toLowerCase().indexOf(onlineStatus.toLowerCase()) > -1
});
//Condition can be applied if filtering is separated
let filteredBySkills = [];
filteredBySkills = this.items.filter((thisUser) => {
return thisUser.skills.some(c => this.filterArr.includes(c.id))
});
//Expecting to join results from multiple filters
return this.items = filteredByStatus.concat(filteredBySkills);
But this is not working at all. Not sure what wrong is there. I am looking for a solution that enables to join arrays of similar objects without duplicating them.
Don't think you need to join arrays for your filtering. You can use something like rxjs filter.
return from(this.items)
.pipe(
filter(user => {
return user.online_status.toLowerCase().indexOf(onlineStatus.toLowerCase()) > -1
&& user.skills.some(c => filterArr.includes(c.id));
})
);
Or if you like to split it up you can just change it to like:
return from(this.items)
.pipe(
filter(user => user.online_status.toLowerCase().indexOf(onlineStatus.toLowerCase()) > -1),
filter(user => user.skills.some(c => filterArr.includes(c.id)))
);
Stackblitz: https://stackblitz.com/edit/angular-pk3w8b
You can tweak your condition a bit and place !this.filterArr.length in your condition (in terms of OR condition AND with user status) to make your whole condition gets true so that user gets filter.

how to group the array of data based on multiple values?

I want to group the data based on the type and type_id
Here is the array
var addArray = [
{
"id": 24,
"language_id": 3,
"type": "service",
"type_id": 2,
"key": "service seeker",
"value": " need service"
},
{
"id": 23,
"language_id": 3,
"type": "service",
"type_id": 2,
"key": "phone",
"value": "phone number"
},
{
"id": 24,
"language_id": 3,
"type": "service",
"type_id": 7,
"key": "tester",
"value": "service tester"
}
{
"id": 19,
"language_id": 3,
"type": "offer",
"type_id": 4,
"key": "source",
"value": "resource"
}
]
I have tried let result = _.groupBy(addArray,'type') it is grouping the data based on type but I need to group by type as well as type_id
Expected output
If you need the a flat grouping based on two or more properties, use the _.groupBy() callback to combine the properties to a string:
const addArray = [{"id":24,"language_id":3,"type":"service","type_id":2,"key":"service seeker","value":" need service"},{"id":23,"language_id":3,"type":"service","type_id":2,"key":"phone","value":"phone number"},{"id":24,"language_id":3,"type":"service","type_id":7,"key":"tester","value":"service tester"},{"id":19,"language_id":3,"type":"offer","type_id":4,"key":"source","value":"resource"}]
const result = _.groupBy(addArray, o => `${o.type}-${o.type_id}`)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
If you need a multi level grouping, start by grouping by the type, then map the groups with _.values(), and group them again by type_id:
const { flow, partialRight: pr, groupBy, mapValues } = _
const fn = flow(
pr(groupBy, 'type'),
pr(mapValues, g => groupBy(g, 'type_id'))
)
const addArray = [{"id":24,"language_id":3,"type":"service","type_id":2,"key":"service seeker","value":" need service"},{"id":23,"language_id":3,"type":"service","type_id":2,"key":"phone","value":"phone number"},{"id":24,"language_id":3,"type":"service","type_id":7,"key":"tester","value":"service tester"},{"id":19,"language_id":3,"type":"offer","type_id":4,"key":"source","value":"resource"}]
const result = fn(addArray)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

Resources