Return object from multiple getJSON responses - javascript

I have a function that calls a paginated API, loops through each of the pages and returns data from from each of the responses:
function nextPage(url) {
if (!url) {
return;
}
$.getJSON(url, function(data) {
nextPage(data.next);
$.each(data.results, function (k, v) {
console.log(v.city_name);
});
});
}
nextPage('http://url.com/api/v1/cities/?page=1');
Currently, when I log the response to the console I get something that looks like this:
Paris
Brussels
Mexico City
...
But what I want is a structure that looks this this:
[
{item: 'Paris'},
{item: 'Brussels'},
{item: 'Mexico City'}
]
For reference the response data looks like this:
{
"count": 105,
"next": "http://url.com/api/v1/cities/?page=2",
"previous": null,
"results": [
{
"city_detail": "http://url.com/api/v1/cities/1/",
"city_name": "Paris"
},
{
"city_detail": "http://url.com/api/v1/cities/2/",
"city_name": "Brussels"
},
{
"city_detail": "http://url.com/api/v1/cities/3/",
"city_name": "Mexico City"
}
]
}
I know the answer is staring me in the face and is probably v. simple, but my lack of javascript knowledge is letting me down. Would appreciate help solving this. Thanks!
EDIT
The problem seems to be that the nextPage function makes multiple calls, returning data from each page of JSON. I can get this data into multiple objects, but not one object representing all the responses.

So basically you want to store key:value pair to an object..:
Dot Notation:
var cities = {}
function nextPage(url) {
if (!url) {
return;
}
$.getJSON(url, function(data) {
nextPage(data.next);
$.each(data.results, function (k, v) {
console.log(v.city_name);
cities.name = v.city_name //Push to an object
});
});
}
So youll get this as a response:
cities = [
{city: 'Paris'},
{city: 'Brussels'},
{city: 'Mexico City'}
]
Bracket Notation:
var cities = {}
function nextPage(url) {
if (!url) {
return;
}
$.getJSON(url, function(data) {
nextPage(data.next);
$.each(data.results, function (k, v) {
console.log(v.city_name);
cities["name"]= v.city_name //Push to an object
});
});
}
Result
:
(Same for both)
cities = [
{city: 'Paris'},
{city: 'Brussels'},
{city: 'Mexico City'}
]
EDIT
Ok so there was another problem! It was sneaky but we finnaly caught it. So the problem was here:
$.getJSON(url, function(data) {
console.log(data.results)
nextPage(data.next);
$.each(data, function (k, v) {
cities["title"]= v.title //Push to an object
});
});
There now, you see it says data.results ... Actually data.results is an empty undefined variable.. What you should do is only data which consists the whole data. You might not understand it now but look over the code i represented below ...
var dataJSON;
function nextPage(url) {
if (!url) {
return;
}
$.getJSON(url, function(data) {
console.log(data) //This consits the data on the below provided url...
dataJSON = data; // Just making a public variable assigned to the data..
nextPage(data.next);
$.each(data, function (k, v) {
});
});
}
nextPage('https://cdn.rawgit.com/amanuel2/Collabs/master/list.json')
Plunker go to console to view data....
EDIT2
Ok this is preety much your JSON File i put in GITHUB, so i have a secure HTTPS://.. Anways here i just did data.results and i got this result:
And here is the Plunker! Hope this helped!!
EDIT3
Ok now this is the last bit.. With your 2nd JSON Page.. You 2nd JSON Page had actually syntax errors.. So i fixed those put it in github and uploaded the new JSON.. Here is the plunker..
Link to Read More about Objects..

var results = []
function nextPage(url) {
if (!url) {
return;
}
$.getJSON(url, function(data) {
nextPage(data.next);
$.each(data.results, function (k, v) {
results.push({item: v.city_name})
console.log(v.city_name);
});
});
}
console.log(results)
// should show an array with {item: city_name} objects.
this allows the results array to be accessed in the outer scoped as well.

Related

Javascript push array inside object

How do I create the data array from my second api call result into the format I want?
I have a code like this
var github = require('octonode');
var client = github.client();
var userName = "octocat";
var repoName = "";
var branchName = "";
var data = [];
var branches = [];
client.get('/users/'+userName+'/repos', {}, function (err, status, body, headers) {
body.forEach(function(obj) {
repoName = obj.name;
//==============================
client.get('repos/'+userName+'/'+repoName+'/branches', {}, function (errx, statusx, bodyChild, headersx) {
bodyChild.forEach(function(objChild) {
branchName = objChild.name;
});
});
});
});
I have received repoName and branchName data as well.
I want my data format like
How to use
data.push({
name: repoName,
branches: 'branchName loooping here for every repoName'
});
so branches repetition data can be contained in my branches tag
Thank you
I guess you can do something like this:
var data = [];
client.get('/users/'+userName+'/repos', {}, function (err, status, body, headers) {
body.forEach(function(obj) {
repoName = obj.name;
client.get('repos/'+userName+'/'+repoName+'/branches', {}, function (errx, statusx, bodyChild, headersx) {
let elem = {"name": repoName, "branches": []}; //create json object for each repo
bodyChild.forEach(function(objChild) {
elem.branches.push(objChild.name); //push all branchs to that elem
});
data.push(elem); // add the elem to the data array
});
});
});
So in this case data is an object, that has a property name which is string, and another property branches which is array. If you want to push data to the property branches you can just call the push() function on it.
Please check the example below:
let data = {
name: "repoName",
branches: [
{
name: "foo"
}
]
}
data.branches.push(
{
name: "bar"
}
);
console.log(data);

calling a json array in angularjs

I have an json array of
[{
"id": "21390238becde1290",
"chelsea": {
"homeTeam": "chelsea",
"sortName": "ches",
"awayTeam": "Maribor",
"awayShort": ""
},
"barclays": {
"id": "21390238becde1290",
"homeTeam": "barclays",
"sortName": "barc",
"awayTeam": "Hull",
"awayShort": ""
}
}]
Controller:
footBallApp.controller('TeamInfoEdit',
function ($rootScope, $scope, $state, $translate, carwashService) {
$rootScope.washTypes;
$scope.onViewLoaded = function () {
matchService.getTeamTypes($scope.TypeSelected);
}
$scope.TypeSelected = function (response) {
debugger;
if (response) {
$rootScope.teamAvailable = response;
$scope.localizedTeamName = getLocalizedCollection($scope.teamAvailable);
}
}
// Editing the Team Details.
$scope.editTeamDetails = function (key) {
console.log(key._id);
$rootScope.selectTeam =[];
for(var i=0; i<$scope.teamAvailable.length;i++){
if($scope.teamAvailable[i]._id== key._id)
{
console.log($scope.teamAvailable[i]);
$scope.selectTeam.push($scope.teamAvailable[i]);
debugger;
And I have assigned the array to $scope.selectTeam. When Im trying to call $scope.selectTeam.chelsea.Im getting it as Undefined in the console. While calling the json I'm going wrong but couldn't find it, so how do I call the array correctly. So looking for help in this.
I don't know how your array looks like, but try to call:
$scope.selectTeam[0].chelsea
Array is coming because of uninitialized.
If you initialize $rootScope.teamAvailable = {}; then if response data comes in json format it will overwrite.

How to synchronize the function commands in angular js

I am creating an ionic application and in particular scenario
when an employee is selected from a list(generated from a JSON data array), his detail is to be shown from here
var employees = [{"id": 325, "firstName": "James", "lastName":
"King", "managerId": 0, "managerName": "", "reports": 4, "title":
"President and CEO", "department": "Corporate", "cellPhone":
"617-000-0001", "officePhone": "781-000-0001", "email":
"jking#gmail.com", "city": "Boston, MA", "pic": "James_King.jpg",
"twitterId": "#fakejking", "blog": "http://coenraets.org"}.....
All i need is to find the index of ID to show the complete object.
findById: function(employeeId) {
var deferred = $q.defer();
var searchValue = {'id': employeeId };
index = -1;
_.each(employees, function(data, idx) {
if (_.isEqual(data, searchValue)) {
index = idx;
return;
}
});
var employee = employees[index];
deferred.resolve(employee);
return deferred.promise;
},
for that i am using this function which is not taking debugger inside the _.each function
kindly tell me where m i wrong.
It's not going to work because expression _.isEqual(employees[xxx], {id: 325}) will never return a match.
Instead use _.find method
findById: function(employeeId) {
var employee = _.find(employees, {id: employeeId});
return $q.when(employee);
}
I think you can simplify your function a little, because you are using lodash:
findById: funtion(employeeId) {
return _.findWhere(employees, {id : employeeId});
}
Futhermore I do not see any reason to use promises here, but to go with that notion, you could try this:
findById: funtion(employeeId) {
var deferred = $q.defer();
$timeout(function() {
var employee = _.findWhere(employees, {id : employeeId});
if (found !== undefined) {
deferred.resolve(employee);
} else {
deferred.reject();
}, 0);
return deferred.promise;
}
You need to return the promise deferred.promise before you resolve() or reject(), so you can wait for that in your callee.
Hope that helps!
I don't know if your really need the index. To work on a solution, which returns the employee at that moment, when you find the data, would be better and shorter. Than you should also jump out of the loop.
If your debugger is not jumping inside _.each maybe your employees array is empty.
You could try something like this:
findById: function(employeeId) {
var deferred = $q.defer();
// deferred should be inside the scope of _.each
// because it is defined here
var searchValue = {'id': employeeId };
//index = -1;
// check your data here
// for example console.log(employees.length)
// or make a breakpoint here and check employees
_.each(employees, function(data, idx) {
// make a console.log(idx) here to check your data
if (_.isEqual(data, searchValue)) {
deferred.resolve(data);
return deferred.promise;;
}
});
},

Firebase retrieve Object by Key in JavaScript Api

Help:
I'm an object of Firebase and can not recover only one item from the list because the key is a objectId and the doc api JS Firebase, it does not have a method to recover for me.
Can you help me?
Controller
var rooms = Rooms.all();
console.log('All Rooms:', rooms);
console.log('Rooms length:', rooms.length);
// New test room
if (!rooms) {
var objRooms = [
{
cc: 'Business 1',
name: 'Chat 1',
city: 'Curitiba',
state: 'PR'
},
{
cc: 'Business 2',
name: 'Chat 2',
city: 'Floripa',
state: 'SC'
}
]
var objRoom = Rooms.save(objRooms);
console.log('ROOMID: ', objRoom.key());
}
Service
.factory('Rooms', function ($firebaseObject) {
// Might use a resource here that returns a JSON array
var ref = new Firebase(firebaseUrl);
var rooms = $firebaseObject(ref.child('rooms'));
return {
all: function () {
return rooms;
},
get: function (roomId) {
// Simple index lookup
console.log('ROOMD:', rooms);
return rooms[ ref.child(roomId) ];
},
save: function (roomData) {
var obj = ref.child('rooms');
var onComplete = function (error) {
if (error) {
console.log('Data could not be saved: ', error);
}
else {
console.log('Data saved successfully!');
}
};
return obj.push(roomData, onComplete);
}
}
})
Output:
Chat Controller initialized!
controllers.js:117 Object {params: Object, current: Object, $current: extend, transition: null}$current: extendcurrent: Objectget: (stateOrName, context)go: go(to, params, options)href: href(stateOrName, params, options)includes: includes(stateOrName, params, options)is: is(stateOrName, params, options)params: ObjectroomId: "-JxlCvzgbdkQfoA1Of78"__proto__: Objectreload: reload()transition: nulltransitionTo: transitionTo(to, toParams, options)__proto__: Object
services.js:78 Selecting the room with id: -JxlCvzgbdkQfoA1Of78
services.js:20 ROOMD: d {$$conf: Object, $id: "rooms", $priority: null}
app.js:43 Logged in as : simplelogin:2
The factory Rooms is a problem:
get: function (roomId) {
// Simple index lookup
console.log('ROOMS:', rooms);
console.log('ROOM specified:', ref.child(roomId).key());
return rooms[ ref.child(roomId) ];
},
[Update]
I created the factory Objects for filter Object data:
.factory('Objects', function () {
return {
filter: function (objectValues, objectKey) {
// to take an action after the data loads, use the $loaded() promise
objectValues.$loaded().then(function () {
// To iterate the key/value pairs of the object, use angular.forEach()
angular.forEach(objectValues, function (value, key) {
if (key === objectKey) {
console.log(objectValues[objectKey]);
return objectValues[objectKey];
}
});
});
}
}
})
and Rooms factory, I edited method get and set:
get: function (roomId) {
return Objects.filter(rooms, roomId);
},
[Update]
I have a database based in the image:
I need list object data.
JavaScript Api
https://www.firebase.com/docs/web/api/
First of all you should use Angularfire which provides some useful methods for using Firebase with AngularJS. You can find the documentation here:
https://www.firebase.com/docs/web/libraries/angular/api.html
Now, your question is how to access an single item using it's key. You can do that simply by just providing the url to that object when retrieving either a $firebaseArray or $firebaseObject (when using Angularfire API):
http://myfirebase.firebase.io/blazing-heat-9118/rooms/ + roomId
And then pass this url to a new Firebase() call:
var ref = new Firebase('http://myfirebase.firebase.io/blazing-heat-9118/rooms/' + roomId);
var room = $firebaseObject(ref);
// To take an action after the data has finished loading, use the $loaded() promise
obj.$loaded().then(function(res) {
console.log(res); // res will be the room object
// To iterate the key/value pairs of the object, use angular.forEach()
angular.forEach(obj, function(value, key) {
console.log(key, value);
});
});
Now you will have fetched the single room from the database.
I'd suggest reading through the Angularfire documentation thoroughly as it contains some great methods for handling your data.

IndexedDB and Javascript: JSON and objects misunderstanding

I'm trying to obtain information from a JSON file download to the client through AJAX and I'm getting different results depending on the JSON format and I don't know how to fix the one with problem.
First case:
The json files looks like:
[{"name": "nick",
"age": 28},
{"name": "katie",
"age": 32}]
My AJAX .done method looks like:
.done(
function(data) {
addObjectsDB (data, "people");
})
This method calls a second one that iterates through data and stored correctly each object into IndexedDB.
Second case:
Now I have a JSON file with different format:
[
{
"husband": {
"name": "Jhon",
"age": 23 },
"wife": {
"name": "Marie",
"age": 24 }
}
]
Now my .done() AJAX method iterates through data and add each person, husband or wife to an array which is then sent to the DB with the same method than the first case:
.done(
function(data) {
var people = [];
$(data).each(function (key, value){
people.push(value.husband);
people.push(value.wife);
});
addObjectsDB (people, "people");
})
In this case the insertion into the database fails, if for example, instead of adding value.husband to people array I just add value to people array the insertion works, but I need each person stored separated in the DB.
The addObjectsDB method is:
function addObjectsDB (data, collection) {
var objectStore = db.transaction(collection, "readwrite").objectStore(collection);
$.each (data, function (key, value) {
var request = objectStore.add(value);
});
}
As I said the first case works perfectly but the second one inserts nothing and no error is showed...
I think the problem is that I don't understand javascript types adequately but I'm starting with it and I've spent a whole evening with it.
There's nothing wrong with your IDB code. Look for your answer in the code you haven't presented, particularily the AJAX response (is your JSON parsed the way you think it is?)
Be sure to attach event listeners for the error event. I'm positive that if your IDB "inserts nothing" then in fact it's not true that "no error is showed" and rather no error is seen due to callback mismanagement.
Here's a working implementation, modified from a previous answer I've given on this tag. This implementation doesn't have the uniqueness constraints you've put on your schema on purpose: it shows that your looping is fine. The entries below all look good.
var db_name = 'SO_22977915',
store_name = 'people';
$.ajax({
url: '/echo/json/',
type: 'post',
dataType: 'json',
data: {
json: JSON.stringify({
case1: [{
"name": "nick",
"age": 28
}, {
"name": "katie",
"age": 32
}],
case2: [{
"husband": {
"name": "Jhon",
"age": 23
},
"wife": {
"name": "Marie",
"age": 24
}
}]
})
},
success: function (data) {
var request,
upgrade = false,
doTx = function (db, entry) {
addData(db, entry, function () {
getData(db);
});
},
getData = function (db) {
db.transaction([store_name], "readonly").objectStore(store_name).openCursor(IDBKeyRange.lowerBound(0)).onsuccess = function (event) {
var cursor = event.target.result;
if (null !== cursor) {
console.log("entry", cursor.value);
cursor.continue();
}
};
},
addData = function (db, entry, finished) {
console.log('adding', entry);
var tx = db.transaction([store_name], "readwrite"),
people = [];
tx.addEventListener('complete', function (e) {
finished();
});
$.each(entry.case1, function (key, value) {
tx.objectStore(store_name).add(value);
});
$(entry.case2).each(function (key, value){
people.push(value.husband);
people.push(value.wife);
});
$.each(people, function (key, value) {
tx.objectStore(store_name).add(value);
});
};
request = window.indexedDB.open(db_name);
request.oncomplete = function (event) {
if (upgrade) {
doTx(request.result, data);
}
};
request.onsuccess = function (event) {
if (!upgrade) {
doTx(request.result, data);
}
};
request.onupgradeneeded = function (event) {
var db = event.target.result;
db.createObjectStore(store_name, {
keyPath: null,
autoIncrement: true
});
}
}
});
A cursor and console.log shows all entries as being added:

Categories

Resources