Angular json, filter unwanted json fields - json

I have an json from backend:
{
"_embedded" : {
"countries" : [ {
"id" : 1,
"name" : "Brazil",
"code" : "BR",
"_links" : {
"self" : {
"href" : "http://localhost:8080/api/countries/1"
},
"country" : {
"href" : "http://localhost:8080/api/countries/1"
},
"states" : {
"href" : "http://localhost:8080/api/countries/1/states"
}
}
}, {
"id" : 2,
"name" : "Canada",
"code" : "CA",
"_links" : {
"self" : {
"href" : "http://localhost:8080/api/countries/2"
},
"country" : {
"href" : "http://localhost:8080/api/countries/2"
},
"states" : {
"href" : "http://localhost:8080/api/countries/2/states"
}
}
}
}
}
And on frontend, I want to get data according to typescript interface:
interface Country {
id: number;
code: string;
name: string;
}
I have a code which maps above json to interface:
getCountries(): Observable<Country[]> {
return this.httpClient.get<CountriesResponse>(this.countriesUrl).pipe(
map(response => <Country[]>response._embedded.countries)
)
}
interface CountriesResponse {
_embedded: {
countries: Country[]
}
}
But after mapping method still returns data which is not present in typescript interface Country, I mean _links field.
Please suggest how to avoid it.
I actually found some solution but still thinks it could be done better:
getCountries(): Observable<Country[]> {
return this.httpClient.get<CountriesResponse>(this.countriesUrl).pipe(
map(response => {
const data: Country[] = response._embedded.countries
return data.map(c => ({
id: c.id,
name: c.name,
code: c.code
}))
})
)
}

Related

Retrieve data from JSON file by ID in Angular. TypeError: items.find is not a function

Trying to get data by id from JSON file, but gives the error in console
TypeError: items.find is not a function
{
"product" :{
"data" : [
{ "itemID" : "1" , "name" : "pen" , "qty" : "8" }`,
{ "itemID" : "2" , "name" : "notepad" , "qty" : "5" }
]
} }
Function I am using where TypeError: items.find is not a function in console
getitems(itemID: string) {
return this.http.get<Array<Fruits>>('assets/localjson.json')
.pipe(
map((items: Array<any>) => {
return items.find((item: Fruits) => {
return item.itemID=== itemID;
});
})
);
}
office.ts
export class officeitems {
itemID: string;
name: string;
qty: string;
}
You need to use your structure correctly. Your structure is an object and you have treated it as an array.
So, you need to get your data from the product attribute because data is your array.
You need to change your getItems method and fix the interface defined.
map((product: any) => { // <- you need to use your interface Product { } instead of any
return product.data.find((item: Fruits) => {
return item.itemID=== itemID;
});
{
"product" :{
"data" : [
{ "itemID" : "1" , "name" : "pen" , "qty" : "8" }`,
{ "itemID" : "2" , "name" : "notepad" , "qty" : "5" }
]
}
}

How to fetch nested values in MongoDB?

I have a 3 layer nested document something like this.
{
"_id" : ObjectId("5b5acaf0589ff6bfb5dd091f"),
"date" : "2018/07/31",
"clock" : [
{
"time" : "10:12:02",
"values" : [
{
"name" : "A1003",
"value" : "777"
},
{
"name" : "A0001",
"value" : "888"
}
]
},
{
"time" : "13:12:02",
"values" : [
{
"name" : "A1003",
"value" : "111"
}
]
}
]
}
I'm able to sort the date by using $gte $lte as below and all values are fetched.
getData(name: string[], fromDate: string, toDate: string): Promise<{ message: string }> {
return this._mongoUtility.testDb
.then(db => {
let collection = db.collection('TestDoc');
let fromOnlyDate = fromDate.split(' ');
let toOnlyDate = toDate.split(' ');
return collection.find({
'date': {
$gte: `${fromOnlyDate[0]}`,
$lte: `${toOnlyDate[1]}`
}
}).toArray();
})
.catch(err => {
return Promise.reject({message: 'Data not found', err: err})
})
}
I want to filter by using time and again by name and should display the value.
I tried in many ways but I'm getting the result. Is there nay other method to do so in MongoDB? Kindly suggest.
Expected output should look like below
0:{date: "2018/07/31 10:12:02", value-A1003: "777", value-A0001: "888"}
1:{date: "2018/07/31 13:12:02", value-A1003: "111"}
you can use the aggregate framwork to achive a simmler result(you cant create attr by value)
db.getCollection('sss').aggregate([
{$unwind:'$clock'},
{$unwind:'$clock.values'},
{$project:{
date: {$concat:[ "$date" ,' ' , "$clock.time" ]},
value:'$clock.values.value',
name:'$clock.values.name'
}}
])

saving in the database variable as ObjectID() MongoDB, NodeJS

I created function which is adding people_id inside array of given card. But there is problem that inserted id is always not as an objectId() where I just need it to be saved as objectId.
When id is added to array i I'm sending whole variable board JSON to nodejs API where is executed function findOneAndUpdate. And here is problem because after saved this arrays is not objectID in Author. Can someone tell me how to make it?
JSON board
{
"_id" : ObjectId("59e096a7622a3825ac24f343"),
"name" : "1",
"users" : [
ObjectId("59cd114cea98d9326ca1c421")
],
"lists" : [
{
"list" : "1",
"cards" : [
{
"name" : "2",
"Author" : [
"59df60fb6fad6224f4f9f22d",
"59df60fb6fad6224f4f9f22d",
"59df60fb6fad6224f4f9f22e"
]
},
{
"name" : "3",
"Author" : []
}
]
},
{
"list" : "fea",
"cards" : [
{
"name" : "card",
"Author" : []
}
]
}
],
"__v" : 0 }
Router:
router.post('/add/member', function (req, res, next) {
console.log(req.body)
Board.findOneAndUpdate({ _id: req.body._id },
{
$set: {
lists : req.body.lists
}
},
{
upsert: true
},
((cards) => {
res.send(cards)
})
)
});
model:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var BoardSchema = new Schema({
name: { type: String, maxlength: 20 },
lists : { type: Array },
users : [{ type : Schema.Types.ObjectId, ref: 'User' }],
});
module.exports = mongoose.model('Board', BoardSchema);
And here is function with adding poeple
$scope.addMemberToCard = (indexList, indexCard, member) => {
$scope.board.lists[indexList].cards[indexCard].Author.push(member);
console.log( $scope.board.lists[indexList].cards[indexCard].Author)
return ApiService.staff.addMemberToCard($scope.board).then(function () {
})
}
You could use the mongoose Types ObjectID method and then transform the string sent into an ObjectID.
const id = new new mongoose.Types.ObjectId(Author);

Query to return a field from a nested json using MongoDB

My database has data in the following format :
{ "_id" : ObjectId( "abcd" ),
"coordinate" : [somevalue, somevalue],
"value" : [
{ "time" : 1,
"characteristics" : "pqrs" },
{ "time" : 10,
"characteristics" : "pqrs" } ] }
I want to find the field closest coordinate and a time that is less than or equal to a given value.
Currently I'm using this query :
db.collection.aggregate({
coordinate: {
$geoNear: [latitude, longitude],
$maxDistance: 10
},
"value.time": {
$lte: 5
}
})
This one returned the entire entry, but what I wanted is the field:
{ "time" : 1, "characteristics" : "pqrs" }
Is it even possible to just return this field ? What if there are multiple result and I just want the one that's closest to my value.time input ?
You can perform an aggregation to :
$match items with specified coordinate and value.time
$filter value array to remove everything < 5
$unwind value array
$group by max value
Query is :
db.collection.aggregate({
$match: {
coordinate: {
$geoNear: [0, 0],
$maxDistance: 10
},
"value.time": {
$lte: 5
}
}
}, {
$project: {
value: {
$filter: {
input: "$value",
as: "value",
cond: { $lte: ["$$value.time", 5] }
}
}
}
}, {
$unwind: "$value"
}, {
$group: {
_id: "$_id",
time: { $max: "$value.time" },
characteristics: { $first: "$value.characteristics" }
}
})
Sample output :
{ "_id" : ObjectId("588a8c3080a14de2d654eb7b"), "time" : 4, "characteristics" : "pqrs" }
{ "_id" : ObjectId("588a89327fe89686fd2210b2"), "time" : 1, "characteristics" : "pqrs" }

how to use aggregate for group and count in mongoose?

I have json object in my db like as follows:
{
'name':'test1',
'game':'cric'
},
{
'name':'test1',
'game':'cric'
},
{
'name':'test1',
'game':'football'
},
{
'name':'test2'
'game':'football'
}
I am trying to get output as follows
{
'name':'test1'
'game':[{cric: 2}, {football:1}],
'totalCount': 3
}
I used aggregate query for that.
group {'_id':{name:'$name'}, {game:{$addToSet:$game}}
project {name : $name, game: $game}
I got output as
{name: 'test1', 'game':[cric, football]}
Now i have question that, how can i get count of game. it current example for cricket it is 2 and for football 1 for test1 user
A similar question is answered here.
For your particular case it would be:
db.collection.aggregate([
{
$group: {
_id: { name: "$name", game: "$game" },
games: { "$push": "$game" },
total: { "$sum": 1 }
}
},
{
$group: {
_id: { name: "$_id.name" },
games: { $addToSet: { game: "$_id.game", sum:"$total" } }
}
}
])
And the result should look like:
{
"result" : [
{
"_id" : {
"name" : "test1"
},
"games" : [
{
"game" : "cric",
"sum" : 2
},
{
"game" : "football",
"sum" : 1
}
]
},
{
"_id" : {
"name" : "test2"
},
"games" : [
{
"game" : "football",
"sum" : 1
}
]
}
],
"ok" : 1
}
Here is my solution to test1 name record
db.getCollection('COLLECTION_NAME').aggregate([
{$match : {name : "test1"}},
{
$group: {
_id: "$game" ,
total: { "$sum": 1 },
name : {$first : "$name"}
}
},
{
$group: {
_id : "$name",
games: { $addToSet: { game: "$_id", sum:"$total" } },
totalCount : {$sum : "$total"}
}
}
])