Access json object which has array - javascript

I' very new to json, I can't seem to access it right variables.
I'm trying to get "username" for example, so that I can create mocks for AngularJS project.
$httpBackend.expectGET('user.json').
respond(Users[ { Username: "bjarnipolo"}, { Username: "yolo"} ]);
{
"Users":[
{
"UserId":1,
"Username":"bjarnipolo",
"Password":null,
"FirstName":"Bjarni Póló",
"LastName":"Súkkulaðisson",
"Ssn":"2412813539",
"Email":"bjarnip08#ru.is",
"Phone":"6903066",
"Roles":"Stjornandi",
"JobTitle":"Scrum Master",
"ImageUrl":"http://us.cdn4.123rf.com/168nwm/nruboc/nruboc0802/nruboc080200034/2557282-a-small-cute-dog-playing-basketball-over-a-black-background.jpg",
"IsActive":true
},
{
"UserId":2,
"Username":"yolo",
"Password":null,
"FirstName":"Brynjólfur YOLO",
"LastName":"Hermannsson",
"Ssn":"0106752040",
"Email":"Binni#example.com",
"Phone":"8995555",
"Roles":"Notandi",
"JobTitle":"Team member",
"ImageUrl":"http://us.cdn4.123rf.com/168nwm/nruboc/nruboc0802/nruboc080200034/2557282-a-small-cute-dog-playing-basketball-over-a-black-background.jpg",
"IsActive":true
}
]
}

I think I found a solution to get what you want.
You can use new Request.JSON. The request should look like this :
new Request.JSON({
url: '/echo/json/',
data: {
json: JSON.encode({
"Users":[
{
"UserId":1,
"Username":"bjarnipolo",
"Password":null,
"FirstName":"Bjarni Póló",
"LastName":"Súkkulaðisson",
"Ssn":"2412813539",
"Email":"bjarnip08#ru.is",
"Phone":"6903066",
"Roles":"Stjornandi",
"JobTitle":"Scrum Master",
"ImageUrl":"http://us.cdn4.123rf.com/168nwm/nruboc/nruboc0802/nruboc080200034/2557282-a-small-cute-dog-playing-basketball-over-a-black-background.jpg",
"IsActive":true
},
{
"UserId":2,
"Username":"yolo",
"Password":null,
"FirstName":"Brynjólfur YOLO",
"LastName":"Hermannsson",
"Ssn":"0106752040",
"Email":"Binni#example.com",
"Phone":"8995555",
"Roles":"Notandi",
"JobTitle":"Team member",
"ImageUrl":"http://us.cdn4.123rf.com/168nwm/nruboc/nruboc0802/nruboc080200034/2557282-a-small-cute-dog-playing-basketball-over-a-black-background.jpg",
"IsActive":true
}
]
}),
},
onSuccess: function(response) {
var jsonObj = response;
alert(jsonObj.Users[1].Username);
jsonObj.Users[1].Username = "dsds";
alert(jsonObj.Users[1].Username);
}
}).send();
Here is the jsFiddle.

Related

I've found a Json data using findById, how do I use it in my code?

I am creating an API that gets Patients data(id and name), Physicians data(id and name) and Appointments(id, phyId, patId, app_date) and displays the Patients appointed to a particular physician. I need to create a remote method in physician.js in such a way that I get related Appointment that has phyId and print the details of the Patients using the patId obtained from appointment.
I'm using loopback 3.
Refer this link for clear idea:
https://loopback.io/doc/en/lb3/HasManyThrough-relations.html
I have related models (Physicians, Patients) that are related by "hasMany" with each other "through" Appointment(another model) and Appointment is related to each of these by belongsTo, in my loopback application and i need to print the Patients of a particular Physician.
Patient data:
[
{
"id": 1,
"name": "Anna Mull"
},
{
"id": 2,
"name": "Paige Trner"
}
]
Physician data:
[
{
"id": 1,
"name": "Cardiologist"
}
]
Appointment data:
[
{
"id": 1,
"physicianId": 1,
"patientId": 1,
"appointmentDate": "2019-01-28T10:06:33.530Z"
},
{
"id": 2,
"physicianId": 1,
"patientId": 2,
"appointmentDate": "2019-01-28T10:06:33.530Z"
}
]
I know there is a method already available to query the Patients of a Physician, but I want to code it myself to learn and also print it in the following format.
My idea is to get all the Appointments having the specific phyId in it and find the patId in those appointment and store it in an array. I then use that array to get the patients from the Patient model. I managed to get the Patient details in a function, but I can only console.log(Patients) but I am not able to display it in the API response.
The following is the format i need it in. (EXPECTED OUTPUT in API response)
Physician:
{
"id": 1,
"name": "Cardiologist"
}
Patients:
[
{
"id": 1,
"name": "Anna Mull"
},
{
"id": 2,
"name": "Paige Trner"
}
]
or any similar format.
I've tried to the same and here is my code.
common/models/physician.js
'use strict';
var app = require('../../server/server');
module.exports = function (Physician) {
Physician.getDetails = function (phyid, cb) {
var Appointments = app.models.Appointment;
var Patient = app.models.Patient;
Physician.findById(phyid, function (err, Physician) {
Appointments.find({ where: { physicianId: phyid } }, function (err, Appointment) {
if (err) {
cb(null, "Errorrrrrrrr", "Errorrrrrr");
}
else {
var patients = [], i = 0;
var patobj= [];
for (i in Appointment) {
patients[i] = Appointment[i].patientId;
//console.log(patients);
Patient.findById(patients[i], function(err, Patients){
if(err){
cb("Error in patients", "--");
}
else{
patobj[i]=Patients;//doesnt have any effect
console.log(Patients);//prints in console
}
});
}
cb(null, Physician, patobj);//only Physician is printed, patobj is empty.
}
});
});
}
Physician.remoteMethod('getDetails', {
http: {
path:
'/:phyid/getDetails',
verb: 'get'
},
accepts: {
arg: 'phyid',
type: 'number'
},
returns: [{
arg: 'Physician',
type: 'Object'
}, {
arg: 'Patient',
type: 'Object'
}]
});
};
I am actually getting this in the API response:
{
"Physician": {
"id": 1,
"name": "Cardiologist"
},
"Patient": []
}
and this in the console:
D:\Project\Project1>node .
Web server listening at: http://localhost:3000
Browse your REST API at http://localhost:3000/explorer
{ name: 'Anna Mull', id: 1 }
{ name: 'Paige Trner', id: 2 }
How am I supposed to get the patient data to be printed in the API response?
You patients are empty because, finding Patients by Id is an asynchronous operation. But the for loop is synchronous. The loop finishes and calls the following line before any of the Patients are found.
cb(null, Physician, patobj);//only Physician is printed, patobj is empty.
You need to wait for all the patients to be found by using either Promise.all or async.each.

Select2 won't load remote json response

I have an API that is called by Select2 (v4.0.5) however the debug message in the console says:
Select2: The AJAX results did not return an array in the results key of the response.
When I review the documentation at Select2's documentation site I seem to be following it correctly. This is the javascript I use on the webpage:
$('#account_id').select2({
debug: true,
minimumInputLength: 3,
dataType: 'json',
ajax: {
url: '/api/account-query',
data: function (params) {
var query = {
search: params.term,
v: "new"
}
return query;
},
}
});
This is the response from the API (sensitive bits redacted):
{
"results": [{
"id": "redacted-1",
"text": "text redacted 1"
},{
"id": "redacted-2",
"text": "text redacted 2"
},{
"id": "redacted-3",
"text": "text redacted 3"
},{
"id": "redacted-4",
"text": "text redacted 4"
},{
"id": "redacted-5",
"text": "text redacted 5"
}]
}
If I take the select2 code and supply it with the static json response (without results prepended, just the array) it works just fine.
What am I missing?
Thanks!
You have to provide the processResults callback function so Select2 able to render result in proper way.
I have created a jsfiddle (https://jsfiddle.net/shcavbng/) demo that doing the same.
$('#account_id').select2({
debug: true,
minimumInputLength: 3,
dataType: 'json',
ajax: {
url: 'https://reqres.in/api/users',
data: function (params) {
console.log('params =>' , params);
var query = {
search: params.term,
v: "new"
}
return query;
},
processResults: function (data) {
console.log('results =>' , data);
data = data.data.reduce(function(o,i){o.push({id:i.id,text:i.first_name});return o;},[]);
console.log('results =>' , data);
return {
results: data
};
}
}
});
I figured it out, and as expected I was overlooking a simple aspect:
Content-Type header needed to be application/json vs text/html

Merge multiple json with the same id

the first json is coming from the API in get this data by making a http call
[
{
"clientid": 1,
"clientname": "facebook",
"forecasted": 18,
},
{
"clientid": 2,
"clientname": "youtube",
"forecasted": 83,
}
]
i create the second json to update the image on the first json
[
{
"clientid": 1,
"clientname": "facebook ",
"img":"images/21747.jpg"
},
{
"clientid": 2,
"clientname": "youtube",
"img": "images/youtube.svg"
},
]
now i need to macth both json base on the same id, and fill the first json that i coming from the api with images of the second json
app.factory('myFactory', function($http){
return{
client: function(callback){
$http({
method: "GET",
url: "http://www.erek.co.za/api/..",
cache:true
}).then(callback);
},
list: function(callback){
$http({
method: "GET",
url: "data/Client.json",
cache:true
}).then(callback);
}
};
});
app.controller('myController', function ($scope, myFactory) {
myFactory.client(function(response){
var data = response.data;
$scope.myClients = data;
})
myFactory.list(function (response) {
var data = response.data;
$scope.dark = data;
})
});
html
<div ng-repeat="client in myClients>
<a href="#{{client.clientid}}"
<div class="client-project-panel">
<div class="client-logo-container">
<div class="client-logo" >
<img ng-src="{{dark[$index].img}}" alt="{{client.clientname}}">
</div>
<div class="project-forecasted">
<h2 class="forecasted-value">{{client.forecasted}}%</h2>
<p>Complete</p>
</div>
</div>
</div>
</a>
You can use Object.assign method.
let array1=[ { "clientid": 1, "clientname": "facebook", "forecasted": 18, }, { "clientid": 2, "clientname": "youtube", "forecasted": 83, } ]
let array2 = [ { "clientid": 1, "clientname": "facebook ", "img":"images/21747.jpg" }, { "clientid": 2, "clientname": "youtube", "img": "images/youtube.svg" } ]
var expected = array1.map(a => Object.assign(a, array2.find(b => b.clientid == a.clientid)));
console.log(expected);
myFactory.client(function(response){
var data = response.data;
var clientsData = data;
// after you fetch the clients get list of images
myFactory.list(function (response) {
var data = response.data;
var clientImages = {}
for(var i=0;i<data.length;i++){
clientImages[data[i].clientid] = data[i].img
}
$scope.dark = clientImages
$scope.myClients = clientsData
})
})
In your template just refer to {{dark[client.clientid]}}
You might want to wrap your html in ng-if="myClients" so that the content is shown only after the data is fetched

local JSON file and data in controller method

This is my code in controller init method:
mycontroller = this
var data = [{
"No": "456980",
"Updates": [{
"Test": "abc"
}, {
"Test": "bca"
}, {
"Test": "dbd"
}]
}, {
"No": "456980",
"Updates": [{
"Test": "abc"
}, {
"Test": "bca"
}, {
"Test": "dbd"
}]
}, {
"No": "456980",
"Updates": [{
"Test": "abc"
}, {
"Test": "bca"
}, {
"Test": "dbd"
}]
}]
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData(data);
//set this model to list control having custom list as aggregation
mycontroller.List1.setModel(oModel);
mycontroller.List1.bindAggregation("items", {
path: "/",
template: mycontroller.List1_template
});
var ListItems = P1Notificationcontroller.list1.getItems();
var ListLength = ListItems.length;
for (var i = 0; i < ListLength; i++) {
var control = "status_vbox-list1-" + i;
sap.ui.getCore().byId(control).bindAggregation("items", {
path: "Updates",
template: new sap.m.Text('', {
text: '{Update}'
})
});
}
view declaration create content
oController.List1 = new sap.m.List("List1", {
headerDesign: sap.m.ListHeaderDesign.Standard
});
oController.List1_template = new sap.m.CustomListItem("McustomlistItem", {
content: [
new sap.m.VBox('', {
items: [
new sap.m.Text('', {
text: "{No}"
})
new sap.m.VBox('status_vbox', {
items: []
})
]
}));
The above code in view and controllers init method works perfectly fine the items in custom list VBox are aggregated from update array in data.
when the same data when maintained in local json file &
by using this line of code
var jsonmodel = new sap.ui.model.json.JSONModel("mockData/local.json");
mycontroller.List1.setModel(jsonmodel)
the loop for VBox is failing because we are not able to loop the object .
when i console.log of both models OData attribute of one model is showing as Array and other as object, because of object the loop is not happening
how can we maintain the same data in local json file to loop the updates attribute to the VBox in custom list item as above.
the issue resolved by calling jquery ajax call to fill the local json model as below
jQuery.ajax({
url: "mockData/Local.json",
dataType: "json",
success: function(data, textStatus, jqXHR) {
var jsonmodel = new sap.ui.model.json.JSONModel();
jsonmodel.setData(data);
sap.ui.getCore().setModel(jsonmodel,'testmodel');
mycontroller.List1.setModel(jsonmodel)
}

Meteor + MongoDB: How to get nested data?

I'm new to Meteor and trying to figure out this issue I have.
I'm trying to load data from the Lessons collection based on the route being passed. e.g if /courses/level1/lesson1/1a is passed then show data
Unfortunately this doesn't work.
Am I on the right path or is there a better way of doing this?
Collection
{
"_id": "YSgr3fvjpEBn7ncRa",
"courseId": "level1",
"lesson": [
{
"lessonId": "lesson1",
"freeLesson": true,
"title": "Lesson 1",
"eachLesson": [
{
"eachLessonId": "1a",
"title": "This is (masculine)",
"video": "839843"
},
{
"eachLessonId": "1b",
"title": "That is (masculine)",
"video": "839843"
},
{
"eachLessonId": "1c",
"title": "This is (feminine)",
"video": "839843"
},
{
"eachLessonId": "1d",
"title": "That is (feminine)",
"video": "839843"
},
{
"eachLessonId": "1e",
"title": "Getting to know you",
"video": "839843"
}
]
}
]
}
Routes
Router.route("courses/:courseId/:lessonId/:eachLessonId", {
path:"/courses/:courseId/:lessonId/:eachLessonId",
layoutTemplate: "layoutLessons",
template:"lessons",
onBeforeAction:function(){
var currentUser = Meteor.userId();
if (currentUser) {
Session.set('courseId', this.params.courseId);
Session.set('lessonId', this.params.lessonId);
Session.set('eachLessonId', this.params.eachLessonId);
this.next();
} else {
Router.go('/')
}
},
});
Template helper
Template.lessons.onCreated(function(){
Meteor.subscribe('listLessons');
});
Template.lessons.helpers({
currentLesson: function() {
var currentLesson = Session.get('eachLessonId');
return Lessons.find({"lesson.eachLesson.eachLessonId" : currentLesson});
},
});
HTML
{{#each currentLesson}}
{{title}}
{{video}}
{{/each}}
Instead of storing courseId, lessonId and eachLessonId as Session values, you could use the Iron Router's waitOn and data option.
For example, you could rewrite your route as follows:
Router.route('/courses/:courseId/:lessonId/:eachLessonId', {
name: 'lessons',
layoutTemplate: 'layoutLessons',
template: 'lessons',
onBeforeAction: function() {
let currentUser = Meteor.user();
if (currentUser) this.next();
else Router.go('/');
},
data: function() {
var doc = Lessons.findOne({
"courseId": this.params.courseId,
"lesson.lessonId": this.params.lessonId,
"lesson.eachLesson.eachLessonId": this.params.eachLessonId
});
if (doc) {
var lesson = {};
var lessonId = this.params.eachLessonId;
_.each(doc.lesson, function(i) {
lesson = _.find(i.eachLesson, function(j) {
return j.eachLessonId == lessonId;
});
});
return lesson;
}
return {};
},
waitOn: function() {
return [
Meteor.subscribe('lesson', this.params.courseId, this.params.lessonId, this.params.eachLessonId)
];
}
});
This should set the data context to the requested eachLesson object. However, you may consider setting the data context to a document in the Lessons collection and then just picking certain eachLesson objects. In addition, you should create a publish function which returns just the requested Lessons document and not all of them, like you probably do now in your listLessons publication. You can pass all IDs as arguments to the corresponding publish function.

Categories