Backend API's:
url: http://www.sample.com/getAllPersons
[
{
"name": "ABC",
"occupation": "Student",
"address_url": "http://www.sample.com/address/person=hgjgjgyyfhg"
},
{
"name": "ABC1",
"occupation": "Carpenter",
"address_url": "http://www.sample.com/address/person=fsdafdsa"
},
{
"name": "ABC2",
"occupation": "Developer"
},
{
"name": "ABC3",
"occupation": "Tester",
"address_url": "http://www.sample.com/address/person=sgdfsgd"
}
]
url: http://www.sample.com/address/person=hash_value
{
"address": "XYZ",
"city": "Phoenix",
"state": "Arizona",
"pin code": "3243242"
}
Need array of objects:-
{
"name": "ABC",
"occupation": "Student",
"address": "XYZ",
"city": "Phoenix",
"state": "Arizona",
"pin code": "3243242"
}
I need to show in a view the name, occupation and full address of every person with the above two api urls.
Note: Every person's address may not be available.
Please suggest the best method to do this asynchronously using HTTP Service and Promises/Observables in Angular 2.
My Solution:
Create http request promise of getAllPersons.
In then function:
Save the response in a component class variable.
Create array of http promises of every object's address_url (if it is present).
Return Promise.all([Array of address url promises])
In then function:
Iterate responses one by one and add them to the component class
variable containing address_url.
Is there any better way? Also suggest if this was a three way hierarchy.
Use flatMap and forkJoin:
var o = http.get('http://www.sample.com/getAllPersons')
.flatMap(t=> Observable.forkJoin(
t.json().filter(x=>x.address_url != null)
.map(y=> http.get(y.address_url).map(t=>json()))
));
Subscribe like this:
o.subscribe(arr=> {
//arr[0] --> address_url[0]
//arr[1] --> address_url[1]
...
});
Related
Building a react native app using CosmosDB and it's SQL api.
Per their documentation, I can add an object to a container like this:
const CosmosClient = require('#azure/cosmos').CosmosClient;
const client = new CosmosClient({ endpoint, key });
const myNewObject = {foo: "bar"}
await client
.database(databaseId)
.container(containerId)
.items.create(myNewObject);
And I can confirm this works.
What I'm trying to do tho, is place data into that {foo: "bar"} document that already exists.
So far I've tried chaining the .item method, but it does't work.
await client
.database(databaseId)
.container(containerId)
.item(idOfMyNewObject) // The existing object I want to create a child in
.item('myNewChildObject') // new child of the parent
.create(newEntry); // new entry in the new child
Any ideas? the documentation doesn't seem to talk about this.
There's no method on the container that does this for you. You must define the structure of the data yourself in your code. Here is an example of a customer record which has both an array of addresses as well as an embedded object.
const customer = {
"id": "000242A2-BF40-4220-864B-2770CAA38F5D",
"type": "customer",
"customerId": "000242A2-BF40-4220-864B-2770CAA38F5D",
"title": "",
"firstName": "Timothy",
"lastName": "Kelly",
"emailAddress": "timothy4#adventure-works.com",
"phoneNumber": "193-555-0189",
"creationDate": "2014-03-14T00:00:00",
"addresses": [
{
"addressLine1": "9918 Scottsdale Rd.",
"addressLine2": "",
"city": "Novato",
"state": "CA ",
"country": "US",
"zipCode": "94947",
"location": {
"type": "Point",
"coordinates": [
-122.764,
38.0852
]
}
}
],
"password": {
"hash": "LvEbgjonEPU11HEeSXqdzTsmqNeUfuhxBNL82vGlCWA=",
"salt": "61626BAE"
},
"salesOrderCount": 1
}
I needed assistance in order to work out why the aggregate function is not responding the way I'd expect it to respond. This is a RESTful API service I've designed in which I am trying to connect collections with each other. Please note the following:
Collection: Season
{
"_id": {
"$oid": "5c0fc60bfb6fc04dd6ea4e9a"
},
"Season": "1",
"TotalEpisode": "15",
"Name": null,
"Description": "First season with no name for this drama",
"PlayID": "5c0fc4aafb6fc04dd6ea4d81"
}
Collection: Play
{
"_id": {
"$oid": "5c0fc4aafb6fc04dd6ea4d81"
},
"Name": "It was the first time",
"Description": "One of the best action heros in the entertainment industry until this day",
"ReleaseDate": "24/12/2010",
"EndingDate": "12/08/2012",
"Category": "Drama"
}
My implemented code in JavaScript
function getTestLookUp(db, collectionName, response, secondCollectionName){
console.log('First collection name: ' + collectionName + '\n' + 'Second collection name: ' + secondCollectionName);
db.collection(collectionName).aggregate([
{
$lookup:
{
from: secondCollectionName,
localField: 'PlayID',
foreignField: '_id',
as: 'requestedDetails'
}
}
]).toArray((err, res) => {
if(err){
console.log(err);
} else {
console.log(res);
response.status(200).json({
'Items': res
});
}
});
}
The response
{
"Items": [
{
"_id": "5c0fc60bfb6fc04dd6ea4e9a",
"Season": "1",
"TotalEpisode": "15",
"Name": null,
"Description": "First season with no name for this drama",
"PlayID": "5c0fc4aafb6fc04dd6ea4d81",
"requestedDetails": []
}
]
}
The things I've checked so far: the collection names are accurate, the ID is also accurate as I can search it up on the MLabs search feature. I don't understand as to why this is returning a empty 'requestedDetails' as I hoped it would return the item from the Play collection.
In addition to this, I would also appreciate if someone can point out how I can join multiple collections instead of 2.
I welcome any questions regarding this problem.
While still researching for this issue, I accidentally came across a another problem in which someone wrote a comment stating that "you might be comparing a String with ObjectID". This was the cause for this error as I obtain a String variable in return from the database and I am comparing the String variable with the _id which is expecting to see a ObjectID variable to complete the query. Therefore, meaning that my query/lookup is never matching these two variables.
The only way tackle this issue is to do a conversion (string to ObjectID) and then compare the values. However, since I'm using the version of ^3.1.10 of MongoDB, this functionality is not possible. Will need to update the version to 4.0 to be able to implement this functionality.
In order to rectify this issue, I managed to surround the foreign ID within $iod tags.
Before
{
"_id": {
"$oid": "5c0fc60bfb6fc04dd6ea4e9a"
},
"Season": "1",
"TotalEpisode": "15",
"Name": null,
"Description": "First season with no name for this drama",
"PlayID": "5c0fc4aafb6fc04dd6ea4d81"
}
After
{
"_id": {
"$oid": "5c0fc60bfb6fc04dd6ea4e9a"
},
"Season": "1",
"TotalEpisode": "15",
"Name": null,
"Description": "First season with no name for this drama",
"PlayID": {
"$oid": "5c0fc4aafb6fc04dd6ea4d81"
}
}
Response
{
"Items": [
{
"_id": "5c0fc60bfb6fc04dd6ea4e9a",
"Season": "1",
"TotalEpisode": "15",
"Name": null,
"Description": "First season with no name for this drama",
"PlayID": "5c0fc4aafb6fc04dd6ea4d81",
"Details": [
{
"_id": "5c0fc4aafb6fc04dd6ea4d81",
"Name": "It was the first time",
"Description": "One of the best action heros in the entertainment industry until this day",
"ReleaseDate": "24/12/2010",
"EndingDate": "12/08/2012",
"Category": "Drama"
}
]
}
]
}
department {
"_id": "1",
"department": "Computers",
"type": "Department",
"room_no": "102",
"HOD": "Mr. G Rahul",
"floor": "1st Floor"
}
student {
"_id": "fdf370e2f43d4af1b505b8913502a5e4",
"_rev": "1-16df9a4cd45ca69009ab6c9767425a8e",
"student Name": "H Ravi",
"date_of_birth": "March 1, 1993",
"roll_no": "55",
"inter_marks": "820",
"secondary_marks": "420"
"department_id": "1",
"type": "student"
}
Map Function
function(doc) {
var id,department,student,hod,dob;
if(doc.type == 'student') {
id = doc.department_id;
dob = new Date(doc.date_of_birth)
student = doc;
}
}
emit(dob, {'_id': id,"student_doc": student});
}
After writing map function we call view by using URL "//localhost:5984/db_name/_design/design_name/_view/view_name". In that URL we will append ?include_docs=true after "view_name"("//localhost:5984/db_name/_design/design_name/_view/view_name/?include_docs=true") to get the docs of by using _id in emit, example: emit(dob,{"_id": id}) it will return the docs of linked id...My question is how can we access that docs in reduce function.
You can’t, the docs are fetched on query time, not on indexing time, so the reduce function never gets to see that data. Sorry!
I'm using ember rc3 and ember-data 12 (sha e324f0e) (basically the files recommended in the guides). I have 2 models set up as follows:
App.User = DS.Model.extend({
username: DS.attr('string'),
playerType: DS.attr('string'),
cars: DS.hasMany('App.Car')
})
App.Car = DS.Model.extend({
name: DS.attr('string'),
thumb: DS.attr('string'),
user: DS.belongsTo('App.User')
})
The json returned is
{
"cars": [
{
"id": "50ace47234fa7557403e7f02",
"name": "Dodge Charger SRT8",
"thumb": "/static/images/carthumbs/18331.png",
"user_id": "502a754b34fa75280c000a7e"
},
{
"id": "508668cc34fa753b78784ca2",
"name": "BMW M3 Coup\u00e9",
"thumb": "/static/images/carthumbs/23250.png",
"user_id": "502a754b34fa75280c000a7e"
},
{
"id": "50c7545334fa750ab8cb3ac2",
"name": "BMW Z4 M Coup\u00e9",
"thumb": "/static/images/carthumbs/7618.png",
"user_id": "502a754b34fa75280c000a7e"
},
{
"id": "50adf64c34fa750bb036121e",
"name": "2013 Ford Shelby GT500\u2122",
"thumb": "/static/images/carthumbs/24824.png",
"user_id": "502a754b34fa75280c000a7e"
}
],
"user": {
"id": "502a754b34fa75280c000a7e",
"car_ids": [
"50ace47234fa7557403e7f02",
"508668cc34fa753b78784ca2",
"50c7545334fa750ab8cb3ac2",
"50adf64c34fa750bb036121e"
],
"player_type": "Standard Player",
"username": "WillMckenzie"
}
}
Everything seems to load fine if I call App.User.find("502a754b34fa75280c000a7e"), but when I try and access the cars property on the user it triggers a second http request to the cars api route. It was my understanding that this shouldn't be necessary, and if I change the ids to basic ints, it doesn't. As I'm using Mongo as my DB my ids have to be in this string format.
Any suggestions as to what I'm doing wrong?
Cheers
Will
Here's the answer so people don't have to dig through the comments:
"I had one car id listed that wasn't in the list of cars returned. They're grabbed slightly differently and I obviously had a bad record in there. This meant it always thought it needed to reload that record so would keep requesting. Obviously when I was faking the integer ids it was masking this." - OiNutter
First, I should point out that I verified my JSON object with http://jsonlint.com and it is, indeed, valid.
Now that is out of the way, I'm looking at examples of the YUI DataTable, specifically the datasource and the structure of the JSON objects the examples use (see http://developer.yahoo.com/yui/examples/datatable/dt_basic.html).
The Basic Example uses a DataSource composed as follows:
YAHOO.example.Data = {
bookorders: [
{id:"po-0167", date:new Date(1980, 2, 24), quantity:1, amount:4, title:"A Book About Nothing"},
{id:"po-0783", date:new Date("January 3, 1983"), quantity:null, amount:12.12345, title:"The Meaning of Life"},
{id:"po-0297", date:new Date(1978, 11, 12), quantity:12, amount:1.25, title:"This Book Was Meant to Be Read Aloud"},
{id:"po-1482", date:new Date("March 11, 1985"), quantity:6, amount:3.5, title:"Read Me Twice"}
]
}
Whereas my JSON object looks like this:
[
{
"Listing": {
"Name": "Jay",
"Address": "Main Street",
"City": "New York"
}
},
{
"Listing": {
"Name": "Thomas",
"Address": "Union Street",
"City": "New York"
}
},
{
"Listing": {
"Name": "Jason",
"Address": "Square Street",
"City": "Boston"
}
}
]
Here is how Yahoo's example specifies the datasource and a few other lines tied to it:
var myDataSource = new YAHOO.util.DataSource(YAHOO.example.Data.bookorders);
myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
myDataSource.responseSchema = {
fields: ["id","date","quantity","amount","title"]
};
In my JSON object, each "Listing" would be a row in the YUI DataTable. What do I need to modify in the YUI code to make it work with my JSON object?
Thank you.
Above you have defined an object, with an unnamed array of objects, each object is composed of another object, with members. While this might be valid JSON, I don't think this is compatible with the expectations of the YUI datatable. It is more of a contrived or obfuscated challenge.
I am unable to provide a way, using the existing JSON object. While your JSON is valid, IMHO, I do not believe it to be compatable with the YUI datatable.
I think you need an object containing a named array of objects that have members, not other objects. There are too many layers in the existing data structure, that serve no apparent purpose, to me.
'Change', below, implies changing the basic datatable example, provided by YAHOO.
Simply restructuring your data like so,
YAHOO.example.Data = {
Listing: [
{
"Name": "Jay",
"Address": "Main Street",
"City": "New York"
},
{
"Name": "Thomas",
"Address": "Union Street",
"City": "New York"
},
{
"Name": "Jason",
"Address": "Square Street",
"City": "Boston"
}
]
};
will simplify your data structure and make this work. This is the minimum change, I believe, considering the constraints.
Then change the datasource:
var myDataSource = new YAHOO.util.DataSource(YAHOO.example.Data.Listing);
and the column defs
var myColumnDefs = [
{key:"Name"},
{key:"Address"},
{key:"City"}
];
and finally the response schema
myDataSource.responseSchema = {
fields: ["Name","Address","City"]
};
Hope that helps.