I have a basic XML request that gets data from a json file stored on my server. Once the request is loaded a function is called that stores the responseText in a variable called data. Once the data is stored, it is then parsed using JSON.parse and stored into a variable called workouts.
Here is my js code:
var data;
var workouts;
var req = new XMLHttpRequest();
req.open("GET", "workout-db.json");
req.onload = function() {
data = req.responseText;
workouts = JSON.parse(data);
}
req.send();
Here is my json code:
[{
"name": "Pull up",
"muscleGroup": "upper",
"imgUrl": "imgs/pull_up.jpg"
},
{
"name": "Battle rope",
"muscleGroup": "upper",
"imgUrl": "imgs/battle_rope.jpg"
},
{
"name": "Push up",
"muscleGroup": "upper",
"imgUrl": "imgs/push_up.jpg"
}
]
Only part I don't understand is how to access this workout object in my code. Trying to call it returns an undefined variable. From what I understand about js scope, the workouts variable should be global and accessible anywhere else in my code.
Related
I have a list of data in my JSON file. I am trying to output certain strings and arrays from my JSON file via my JS. How do I go on about this? All these files are saved on my desktop.
I've tried Xhttp code. But I think I need some server going on for that, and I don't have that. Also, I'm pretty sure this should be possible without having to use a server?
PS: the json file is named: movie.json
JSON CODE
{
"movie": {
"name": "drive",
"year": "2011",
"people": {
"actors": [
{
"name": "ryan gosling"
},
{
"name": "cary mulligan"
},
{
"name": "bryan cranston"
}
]
}
}
}
JS CODE
function preload() {
var movie = load.JSON("movie.json");
}
function(movie) {
var movie = JSON.parse(movie);
console.log(movie[0].name);
console.log(movie[0].year);
console.log(movie[0].actors);
}();
drive, 2011, ryan gosling, cary mulligan, bryan cranston
var movie;
var http = new XMLHttpRequest();
xhhtp.open( "GET", "movie.json", true);
xhttp.onreadystatechange = function () {
if(http.readyState == 4 && http.status == 200) {
movie = JSON.parse(http.responseText);
}
}
http.send();
console.log(movie[0].name);
console.log(movie[0].year);
console.log(movie[0].actors);
I do not know if the code above will help you. Using XMLHttpRequest will help you fetch the json file then you can parse and sort into array. Note: you do not need a server to use XMLHttpRequest, if you have text editor like VSCode you can us it to run live HTML codes then you can get the full link to the JSON file you want to parse e.g localhost:9000/movie.json
Currently I am sending the data as parameter in URL.
Ex
var url = "http://localhost:8080/test?param1=" + param1Value+ "¶m2="+ param2Value;
I am using XMLHttpRequest to communicated.
But by doing this I can see the params in requested URL.
How can I send the data without passing as parameter? (Basically how do I hide those data).
And on server how do I retrieve that?
You could simply use jquery to create a POST form, fill it up, and submit it on the fly.
$("body").append("<form id='form1' action='http://localhost:8080/test' method='POST'></form>");
$("<input></input>", {
"type": "text",
"name": "param1",
"value": param1Value
}).appendTo("#form1");
$("<input></input>", {
"type": "text",
"name": "param2",
"value": param2Value
}).appendTo("#form1");
var theForm = $("#form1");
theForm.hide();
theForm.submit();
I am trying to get JSON data from REST displaying on a web page using javascript
I have the following REST call working fine to the firefox console
function gethosts() {
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "https://10.10.10.10/api/machine", false);
xhttp.setRequestHeader("Content-type", "application/json");
xhttp.send();
var response = JSON.parse(xhttp.responseText);
}
The JSON data is the following,
{
"offset": 0,
"hosts": [
{
"id": "422022c0-4ca7-66a2-bf73-9b56a65c9d2f",
"name": "System Z",
"type": "ORIGINAL",
"model": "System X",
"version": "Release 01",
"management_ip": "10.10.10.11",
"state": "ALIVE",
"date": "2017-01-05T17:55:58Z"
},
I want this displayed using html
Name: System Z
Model: System X
Version: Release 01
MGMT IP: 10.10.10.11
State: ALIVE
I tried adding this to the function but it doesn't seem to work
obj.hosts[0].name// return name
obj.hosts[0].model // return model
$( "body" ).append("<div>"+obj.hosts[0].name+"</div>")
$( "body" ).append("<div>"+obj.hosts[0].model+"</div>")
The sample HTML code is,
<button type="button" onclick="gethosts()">Get all Hosts</button>
<div id="gethosts">Hosts: </div>
Where did obj come from? response is the parsed JSON.
function gethosts() {
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "https://10.10.10.10/api/machine", false);
xhttp.setRequestHeader("Content-type", "application/json");
xhttp.send();
var response = JSON.parse(xhttp.responseText);
$("body").append("<div>"+response.hosts[0].name+"</div>")
$("body").append("<div>"+response.hosts[0].model+"</div>")
}
Also, why the mix of vanilla JS and jQuery? Why not use $.ajax if you already have jQuery loaded?
Let's say I have a animals.json file with the following content:
{
"animals": {
"elephant": {
"size": "large"
},
"mouse": {
"size": "small"
}
}
}
And I'm adding that data to the scope of my controller:
animalsApp.controller('animalsCtrl', function($scope, $http){
$http.get('../../animals.json').success(function(data){
$scope.animals = data.animals;
});
});
Which works perfectly, however let's say I need to get some data from an API that I need to add to $scope.animals, which has the following data:
{
"animal_name": "Leonardo"
}
Which is returned when I go to the api with the jsons data:
http://api.someapi.com/animals/{animals.elepahant} // returns above json
Pretend {animals.elaphant} is the results I get when i loop my json, get a value from it, and get the data from a remote api with the query being a variable of mines, add results to my json and return that new modified json in $scope.animals.
So the final json would look like:
{
"animals": {
"elephant": {
"size": "large",
"name": "Leonardo"
},
"mouse": {
"size": "small",
"name": "Vader"
}
}
}
How can I achieve this?
Normally you would have an array of animals and loop through that array.
Since you have an object the principle is the same. It is important to use a closure for the loop. Will use angular.forEach() to create that closure.
Using for loops by themselves do not create a closure and can be problematic since the loop finishes long before the request responses are returned
$http.get('../../animals.json').success(function(data){
$scope.animals = data.animals;
angular.forEach(data.animals, function(v, animal_type){
var url = 'http://api.someapi.com/animals/' + animal_type;
$http.get(url).success(function(resp){
v.name = resp.animal_name;
});
});
});
There are also alternative ways to write this using chained promises.
I kept it simple for now
I have a AngularJS-based frontend using restangular to fetch records from a Django backend I've built.
I'm making a call for a client list with the following:
var app;
app = angular.module("myApp", ["restangular"]).config(function(RestangularProvider) {
RestangularProvider.setBaseUrl("http://172.16.91.149:8000/client/v1");
RestangularProvider.setResponseExtractor(function(response, operation) {
return response.objects;
});
return RestangularProvider.setRequestSuffix("/?callback=abc123");
});
angular.module("myApp").controller("MainCtrl", function($scope, Restangular) {
return $scope.client = Restangular.all("client").getList();
});
Chrome is showing the backend returning data with an HTTP 200:
abc123({
"meta": {
"limit": 20,
"next": "/client/v1/client/?callback=abc123&limit=20&offset=20",
"offset": 0,
"previous": null,
"total_count": 2
},
"objects": [{
"id": 1,
"name": "Test",
"resource_uri": "/client/v1/client/1/"
}, {
"id": 2,
"name": "Test 2",
"resource_uri": "/client/v1/client/2/"
}]
})
But once that happens I'm seeing the following stack trace appear in Chrome's console:
TypeError: Cannot set property 'route' of undefined
at restangularizeBase (http://172.16.91.149:9000/components/restangular/src/restangular.js:395:56)
at restangularizeCollection (http://172.16.91.149:9000/components/restangular/src/restangular.js:499:35)
at http://172.16.91.149:9000/components/restangular/src/restangular.js:556:44
at wrappedCallback (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:6846:59)
at http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:6883:26
at Object.Scope.$eval (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:8057:28)
at Object.Scope.$digest (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:7922:25)
at Object.Scope.$apply (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:8143:24)
at done (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:9170:20)
at completeRequest (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:9333:7) angular.js:5754
I did a breakpoint on line 395 in in restangular.js:
L394 function restangularizeBase(parent, elem, route) {
L395 elem[config.restangularFields.route] = route;
The first time it hits the breakpoint elem is just an object and route has the value of client.
The second time the breakpoint is hit elem is undefined and route has the value of client.
Any ideas why elem would be undefined the second time around?
When requesting lists, Restangular expects the data from the server to be a simple array. However, if the resulting data is wrapped with result metadata, such as pagination info, it falls apart.
If you are using Django REST Framework, it will return results wrapped like this:
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"name": "Foo"
},
{
"id": 2,
"name": "Bar"
}
]
}
To translate this, you need to create a response extractor function. It's easiest to specify in the module config:
angular.module('myApp', ['myApp.controllers', 'restangular']).
config(function(RestangularProvider) {
RestangularProvider.setBaseUrl("/api");
// This function is used to map the JSON data to something Restangular
// expects
RestangularProvider.setResponseExtractor(function(response, operation, what, url) {
if (operation === "getList") {
// Use results as the return type, and save the result metadata
// in _resultmeta
var newResponse = response.results;
newResponse._resultmeta = {
"count": response.count,
"next": response.next,
"previous": response.previous
};
return newResponse;
}
return response;
});
});
This rearranges the results to be a simple array, with an additional property of _resultmeta, containing the metadata. Restangular will do it's thing with the array, and it's objects, and you can access the _resultmeta property when handling the array as you would expect.
I'm the creator of Restangular.
The restangularizeBase function is called first for your collection and then for each of your elements.
From the StackTrace, the element is OK, but once the collection is sent to restangularizeBase, it's actually undefined. Could you please console.log response.objects? Also, please update to the latest version.
Also, for the default request parameter, you should be using defaultRequestParams instead of the requestSuffix. requestSuffix should only be used for the ending "/"
Let me know if I can help you some more!