How to loop through JSON array in nodejs? - javascript

I'm trying to read value from json array to display in the page. I have tried with below code but couldn't make it. I was trying long time to get this done and Please advise what am I doing wrong here.
Also I'm not able to do JSON.parse- unexpected input error.
http.request(options, function(res) {
res.on('data', function (result) {
console.log(result);//Displaying below format of result without any error
console.log(result.Reference[0].name); Error //TypeError: Cannot read property '0' of undefined.
console.log(result.Reference.length);//Error TypeError: Cannot read property 'length' of undefined
JSON format: when printing result
{
"Reference": [
{
"name": "xxxxxxxx",
"typeReference": {
"articulation": 0,
"locked": false,
"createdBy": {
"userName": "System",
},
"lastModifiedBy": {
"userName": "System",
},
"lastModified": 1391084398660,
"createdOn": 1391084398647,
"isSystem": true
},
"communityReference": {
"name": "xxxxxx",
"language": "English",
"sbvr": false,
"parentReference": {
"name": "xxxxx",
"sbvr": false,
"meta": false,
"parentReference": null,
"locked": false,
"createdBy": {
"userName": "xxxxx",
},
"lastModifiedBy": {
"userName": "xxxxx",
},
"lastModified": 1459185726230,
"createdOn": 1456337723119,
"isSystem": false
},
"locked": false,
"createdBy": {
"userName": "xxxxx",
},
"lastModifiedBy": {
"userName": "xxxxxx",
},
"lastModified": 1472655031590,
"createdOn": 1472654988012,
"isSystem": false
},
"locked": false,
"createdBy": {
"userName": "xxxxx",
},
"lastModifiedBy": {
"userName": "xxxxx",
"firstName": "xxxxx",
},
"lastModified": 1473171981520,
"createdOn": 1472655253366,
"isSystem": false
},
{
"name":"yyyyyy", same attribute type as above.
...
},
{
..
},

res is a stream, and the data event indicates that it has received some data, but it may or may not be all the data. You're not likely to get all the data at once, so you need to wait until the end event fires, when you have the whole JSON object:
var json = '';
res.on('data', function ( chunk ) {
json += chunk;
} );
res.on('end', function ( ) {
var result = JSON.parse( json );
console.log( result.Reference[0].name );
} );
or you can use json-stream which can read in JSON chunk by chunk and handle that correctly, unlike JSON.parse.
However, I recommend that you don't use either of the above solutions and instead use request, which greatly simplifies this and other aspects of making HTTP requests and handling the response.

You can try this with some additional and safe validations:
{
if ( result ) {
var data = (typeof result == "string") ? JSON.parse(result) : result;
if (data.hasOwnProperty("Reference")) {
for(var i = 0; i < data.Reference.length; i++; ) {
try {
var reference = data.Reference[i];
console.log("Name:" + reference.name);
//Your app logic
} catch(e) {
//In case if any invalid references, then continue with others
console.warn("Error processing reference - " + e);
}
}
} else {
console.warn("No References were found!");
}
} else {
console.error("Invalid JSON!");
}
}
Hope it helps!

Related

Why are asset attributes missing from Imgix Management API?

I am querying the Imgix Management API with no issue. I can retrieve an individual asset and a list of assets. However, most of the data properties are null. It looks like this:
{
"data": {
"attributes": {
"analyzed_content_warnings": null,
"analyzed_faces": null,
"analyzed_tags": null,
"categories": null,
"color_model": null,
"color_profile": null,
"colors": null,
"content_type": "image/jpeg",
"custom_fields": null,
"date_created": 1667935028,
"date_modified": null,
"description": null,
"dpi_height": null,
"dpi_width": null,
"face_count": null,
"file_size": 1016205,
"has_frames": null,
"media_height": null,
"media_kind": "IMAGE",
"media_width": null,
"name": null,
"origin_path": "/test/roses.jpeg",
"source_id": "XXXXXXXXXXXXXXXXXXXX",
"tags": null,
"uploaded_by": null,
"uploaded_by_api": false,
"warning_adult": null,
"warning_medical": null,
"warning_racy": null,
"warning_spoof": null,
"warning_violence": null
},
"id": "XXXXXXXXXXXXXXXXXXX/test/roses.jpeg",
"type": "assets"
},
"included": [],
"jsonapi": {
"version": "1.0"
},
"meta": {
"authentication": {
"authorized": true,
"clientId": null,
"mode": "PUBLIC_APIKEY",
"modeTitle": "Public API Key",
"tag": "XXXXXXXXXXXXXXX",
"user": null
},
"server": {
"commit": "7c78ee15",
"status": {
"healthy": true,
"read_only": false,
"tombstone": false
},
"version": "3.187.0"
}
}
}
I'm missing data.colors, data.media_height, data.media_width.
My code is very basic:
import fetch from 'node-fetch'
const imgix_key = 'xxxxxxxx'
const imgix_source_id = 'xxxxxxxx'
const imgix_url = `https://api.imgix.com/api/v1/assets/${imgix_source_id}/test/roses.jpeg`
async function init() {
const method = 'get'
const headers = {
Authorization: `Bearer ${imgix_key}`,
'Content-Type': 'application/x-www-form-urlencoded',
}
const response = await fetch(imgix_url, { headers, method })
const body = await response.text()
console.log(body)
}
init()
I can access data.colors if I request this image from the rendering API with the palette=json parameter, so I know the property theoretically exists.
Request to https://xxxxxxx.imgix.net/test/roses.jpeg?palette=json:
{
"colors":[
{
"red":0.960784,
"hex":"#f5ece9",
"blue":0.913725,
"green":0.92549
},
{
"red":0.843137,
"hex":"#d7cb99",
"blue":0.6,
"green":0.796078
},
{
"red":0.768627,
"hex":"#c44535",
"blue":0.207843,
"green":0.270588
},
{
"red":0.670588,
"hex":"#aba544",
"blue":0.266667,
"green":0.647059
},
{
"red":0.454902,
"hex":"#746a4f",
"blue":0.309804,
"green":0.415686
},
{
"red":0.227451,
"hex":"#3a452f",
"blue":0.184314,
"green":0.270588
}
],
"average_luminance":0.387471,
"dominant_colors":{
"vibrant":{
"red":0.698039,
"hex":"#b2524d",
"blue":0.301961,
"green":0.321569
},
"muted_light":{
"red":0.823529,
"hex":"#d2b3aa",
"blue":0.666667,
"green":0.701961
},
"muted":{
"red":0.698039,
"hex":"#b2524d",
"blue":0.301961,
"green":0.321569
},
"vibrant_dark":{
"red":0.368627,
"hex":"#5e220c",
"blue":0.0470588,
"green":0.133333
},
"vibrant_light":{
"red":0.898039,
"hex":"#e5c699",
"blue":0.6,
"green":0.776471
},
"muted_dark":{
"red":0.305882,
"hex":"#4e3529",
"blue":0.160784,
"green":0.207843
}
}
}
I've tried adding a fields parameter, like this:
https://api.imgix.com/api/v1/assets/xxxxxxxxxxxxxx/test/roses.jpeg?fields[assets]=name,origin_path,colors,media_width,media_height
I get the specified properties, but they're still null.
Could anyone help me understand why these properties are coming back null?
I would like to write a prebuild script to cache the image metadata so I can set image dimensions and colorful placeholder blocks.
Thanks
I would encourage you to write into our support team (support#imgix.com) with this issue. The reason these fields return null is likely tied to your account/Source settings, which they can help you navigate. Hope that helps.

How do I select an adjacent value from a JSON array using map()?

I have some JSON as shown below...
var JSONobj = {
"headline":{
"localized":{
"en_US":"Doctor"
},
"preferredLocale":{
"country":"US",
"language":"en"
}
},
"identities":[
{
"access_token":"AQVUTBfbOs5JLsdfsdfH_W1aZ2N0PrbL0LhD5Y5-g",
"provider":"linkedin",
"user_id":"v57678565vf",
"connection":"linkedin",
"isSocial":true
},
{
"access_token":"AQVUTBsdfsdfsdfsdfwePrbL0LhD5Y5-g",
"provider":"facebook",
"user_id":"hshs8722",
"connection":"facebook",
"isSocial":true
}
],
"name":"John Bob"
};
Using JavaScript I need to go through each item in the "identities" array, find the item with a "connection" value of "facebook", and return the associated "access_token" value.
Note: This example has two items in the "identities" array, but in production there will a dynamic number of items. Sometimes more, sometimes less.
I have been trying to do it using map() as shown below, but I can't figure it out.
var access_token = JSONobj.identities.map(i=>i.connection);
console.log(access_token);
You can use Array.find to find the first object in identities that has a connection of "facebook", then extract the access_token from that object:
var JSONobj = {
"headline": {
"localized": {
"en_US": "Doctor"
},
"preferredLocale": {
"country": "US",
"language": "en"
}
},
"identities": [{
"access_token": "AQVUTBfbOs5JLsdfsdfH_W1aZ2N0PrbL0LhD5Y5-g",
"provider": "linkedin",
"user_id": "v57678565vf",
"connection": "linkedin",
"isSocial": true
},
{
"access_token": "AQVUTBsdfsdfsdfsdfwePrbL0LhD5Y5-g",
"provider": "facebook",
"user_id": "hshs8722",
"connection": "facebook",
"isSocial": true
}
],
"name": "John Bob"
};
var access_token = JSONobj.identities.find(o => o.connection == 'facebook').access_token;
console.log(access_token);
Note (as pointed out by #secan) that if it's possible that there might not be an identity with a connection of "facebook", it is safer to use:
(JSONobj.identities.find(i=>i.connection === 'facebook')||{}).access_token;
as this will return undefined rather than raising an error.
Another alternative in that situation (as pointed out by #pilchard) is to use optional chaining (although this requires a fairly recent browser for support):
JSONobj.identities.find(i=>i.connection === 'Facebook')?.access_token;
create a generala function wich accept identities array and required connection name,
you can use Array.find to go through connection array items
function getAccessToken(identitiesArr, connection) {
let identity = identitiesArr.find(e => e.connection == connection);
if (identity)
return identity.access_token;
return '';
}
var JSONobj = {
"headline": {
"localized": {
"en_US": "Doctor"
},
"preferredLocale": {
"country": "US",
"language": "en"
}
},
"identities": [{
"access_token": "AQVUTBfbOs5JLsdfsdfH_W1aZ2N0PrbL0LhD5Y5-g",
"provider": "linkedin",
"user_id": "v57678565vf",
"connection": "linkedin",
"isSocial": true
},
{
"access_token": "AQVUTBsdfsdfsdfsdfwePrbL0LhD5Y5-g",
"provider": "facebook",
"user_id": "hshs8722",
"connection": "facebook",
"isSocial": true
}
],
"name": "John Bob"
};
let token = getAccessToken(JSONobj.identities, "facebook");
console.log(token);

How to get whole okhttp3 json response and print data?

I'm trying to get account information from site. I am not sure even how to do that. Am using okhttp3.
I would like to retrieve the whole json object and print it out to see the data. I'd liek to see the whole object first but also retrieve only pieces too.
am told to make use GET using this
app.get("/account", async (req, res) => {
console.log(">>>Retrieving");
const account = await stripe.accounts.retrieve(
'acct_1234'
);
});
Then should get object like this
{
"id": "acct_1234",
"object": "account",
"business_profile": {
"mcc": null,
"name": null,
"product_description": null,
"support_address": null,
"support_email": null,
"support_phone": null,
"support_url": null,
"url": null
},
"business_type": null,
"capabilities": {
"card_payments": "active",
"transfers": "active"
},
"charges_enabled": false,
"country": "CA",
"created": 1599337777,
"default_currency": "cad",
"details_submitted": false,
"email": "email#gmail.com",
"external_accounts": {
"object": "list",
"data": [],
"has_more": false,
"url": "/v1/accounts/acct_1234/external_accounts"
},
"metadata": {},
"payouts_enabled": false,
"requirements": {
"current_deadline": null,
"currently_due": [
"business_profile.product_description",
"business_profile.support_phone",
"business_profile.url",
"external_account",
"tos_acceptance.date",
"tos_acceptance.ip"
],
"disabled_reason": "requirements.past_due",
"errors": [],
"eventually_due": [
"business_profile.product_description",
"business_profile.support_phone",
"business_profile.url",
"external_account",
"tos_acceptance.date",
"tos_acceptance.ip"
],
"past_due": [],
"pending_verification": []
},
"settings": {
"bacs_debit_payments": {},
"branding": {
"icon": null,
"logo": null,
"primary_color": null,
"secondary_color": null
},
"card_payments": {
"decline_on": {
"avs_failure": false,
"cvc_failure": true
},
"statement_descriptor_prefix": null
},
"dashboard": {
"display_name": null,
"timezone": "America/Toronto"
},
"payments": {
"statement_descriptor": "",
"statement_descriptor_kana": null,
"statement_descriptor_kanji": null
},
"payouts": {
"debit_negative_balances": true,
"schedule": {
"delay_days": 7,
"interval": "daily"
},
"statement_descriptor": null
}
},
"tos_acceptance": {
"date": null,
"ip": null,
"user_agent": null
},
"type": "custom"
}
Am using Stripe Api here >>>https://stripe.com/docs/api/accounts/create
I've looked around but am not really understanding, am pretty new at using nodejs and okhttp3. Any advice helps. Thank you
I figured it all out. First i had to change the nodejs to\
app.get("/account", async (req, res) => {
console.log(">>>Retrieving");
res.json(await stripe.accounts.retrieve(
'acct_1234'
));
});
And the http request to display all the data and specific values
public void sendGetRequest(String url){
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(30, TimeUnit.SECONDS);
builder.readTimeout(30, TimeUnit.SECONDS);
builder.writeTimeout(30, TimeUnit.SECONDS);
httpClient = builder.build();
Request request = new Request.Builder().url(url).build();
try (Response response = httpClient.newCall(request).execute()) {
String responseBody = response.body().string();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String perfectJSON = gson.toJson(JsonParser.parseString(responseBody));
JSONObject json = new JSONObject(perfectJSON);
JSONObject business = json.getJSONObject("business_profile");
String phone = business.getString("support_phone");
String id = json.getString("id");
this.displayAlert(id+" > "+phone,perfectJSON);
}catch (Exception e){
e.printStackTrace();
}
}

Loopback embedsMany Helper methods don't work

I have these two models:
Student
{
"name": "student",
"plural": "students",
"base": "User",
"idInjection": false,
"options": {
"validateUpsert": true
},
"relations": {
"test": {
"type": "embedsMany",
"model": "test",
"property": "mytest",
"options": {
"validate": true,
"forceId": false
}
}
}
and
Test
{
"name": "test",
"base": "Model",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"text": {
"type": "string",
"required": true
}
}
}
When I try to create a new test I get this error
Error: Invalid reference: undefined
I create the test in this way:
Student.js
studentInstance.test.add({text : "something "})
What am I doing wrong?
Update
Delete in embedsMany
update id in test.
Student.js
Student.show = function(email, cb) {
Student.findById(email,function(err, student) {
...
var tmp = student.mytest;
for (var i = 0; i < tmp.length; i++) {
student.test.destroy(tmp[i].id);
}
})
...
}
I tried with
destroy not work correctly, not always remove the data
and
remove show this error
Error: Invalid reference: undefined
at EmbedsMany.remove
Update
Added a example of db
{
"_id": "value",
"property1": "value",
.
.
"mytest": [
{
"text": "something",
"creation": {
"$date": "2016-08-23T14:31:44.678Z"
},
"id": "d738253472876b17feb4b46b"
}
]
}
You don't have test model.
In test.json you defined its names as notification => "name": "notification",
UPDATE
For building (without persisting) an embedded instance please use studentInstance.test.build({text : "something "})
and for creating (with persisting) that please use studentInstance.test.create({text : "something "})
After 3 years, I've faced with same problem by using remove, destroyById.
And then I use unset method. It works.
Person.findById(body.metadata.person.id, (err, person) => {
person.creditCards.unset(
body.creditCard.id,
(err, res) => {
}
);
}
This works well.

Why are relations not being added to my loopback.io objects in the models?

I am quite new to Loopback and NodeJS, so please tell me if there is a "Node way" of doing something that I am missing. I decided to write a basic application to try and learn more.
I have two models, 'UserInformation' and 'ClothingArticle'. I have created a 'hasMany' relation from UserInformation to ClothingArticle.
As a basic test, I wanted to add a remote method to UserInformation to get recommendations for ClothingArticles. However, I cannot seem to get access to anything related to ClothingArticles. I added code into the common/models/user-information.js file to try and retrieve information about the relation, but am not sure if this is even the right spot to be putting it.
My code is below, could you help?
common/models/user-information.js:
module.exports = function(UserInformation) {
get_methods = function(obj) {
var result = [];
for(var id in obj) {
try {
if(typeof(obj[id]) == "function") {
result.push(id + " (function): "); //+ obj[id].toString());
}
else
result.push(id + ": "); // + obj[id].toString());
}
catch (err) {
result.push(id + ": inaccessible");
}
}
return result;
}
// This doesn't anything about my new relations?
console.log(get_methods(UserInformation.prototype));
UserInformation.recommendations = function(source, callback) {
var response = "I don't have any recommendations.";
var test_function = UserInformation.findById(3, function(err, instances) {
if(err) return console.log("Errors: " + err);
console.log("Instances: " + String(instances));
// Nothing here either about the relations.
console.log(get_methods(UserInformation));
console.log(UserInformation.app);
/*
instances.clothingArticles.create({
id:92,
colors:['red','blue']
});
*/
console.log("Created a new clothing article.");
});
console.log (response);
callback(null, response);
}
UserInformation.remoteMethod(
'recommendations',
{
accepts: [
{arg: 'source', type: 'string'} // Used to mark the source (closet, generic, etc)
],
http: {path: '/recommendations', verb: 'get'},
returns: {arg: 'recommendations', type: 'string'}
}
);
};
common/models/user-information.json:
{
"name": "UserInformation",
"base": "PersistedModel",
"strict": false,
"idInjection": false,
"properties": {
"birthday": {
"type": "date"
},
"id": {
"type": "number",
"id": true,
"required": true
},
"eye_color": {
"type": "string"
},
"hair_color": {
"type": "string"
},
"weight": {
"type": "string",
"comments": "pounds"
},
"height": {
"type": "number",
"comments": "inches"
}
},
"validations": [],
"relations": {
"clothingArticles": {
"type": "hasMany",
"model": "ClothingArticle",
"foreignKey": "owner_id"
}
},
"acls": [],
"methods": []
}
common/models/clothing-article.json:
{
"name": "ClothingArticle",
"base": "PersistedModel",
"strict": false,
"idInjection": false,
"properties": {
"id": {
"type": "number",
"id": true,
"required": true
},
"colors": {
"type": [
"Color"
],
"required": true
},
"owner_id": {
"type": "number"
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": []
}
I suggest starting with our getting started example and working your way through through the tutorial series here: https://github.com/strongloop/loopback-example
The questions you ask are answered throughout the examples (ie. model relations). To answer your question, if you defined a relation properly, you should be able to access the relation via dot.
...
UserInformation.ClothingArticle...
...
See http://docs.strongloop.com/display/LB/HasMany+relations for more information.

Categories