How to get JSON object data from a webpage using javascript - javascript

I am new to web and I need to get JSON object for a webpage that has data displayed this:
{
"expires": "2011-09-24T01:00:00",
"currencies": {
"BZD": {
"a": "2.02200",
"b": "1.94826"
},
"YER": {
"a": "220.050",
"b": "212.950"
}
}
I tried use jquery's $.getJSON to get the object but it didn't work.
<script>
$.getJSON("http://m.somewebsite.com/data",
{
format: "json"
},
function(data) {
document.getElementById('test').innerHTML = data;
});
</script>
I am wondering how to get this information correctly?

In order for this to work, you need to define jsonp, jsonp allows you to gain read access to another site's document, as the alternate version is barred.
$.getJSON("http://m.somewebsite.com/data?callback=?", { format: "json" }, function(data) { document.write(data); });

Related

Consuming handlebars.js template generated from ajax response

The handlebars.js template is generated server side and returned as part of the response.
"<div>{{name}}<small style='color:#999;'><br><code>{{vafm}}</code></small><br><code>{{email}}</code></div>"
.
var t = "";
$('#UniqueId').select2({
ajax: {
url: '/search/endpoint',
dataType: 'json',
processResults: function (data) {
t = data.template;
return {
results: data.results
};
},
},
templateResult: Handlebars.compile(t),
escapeMarkup: function (m) {
return m;
}
});
Unfortunately the rendered part on select2 does not contain the values returned by the data.results
I have located the issue to this line
templateResult: Handlebars.compile(t),
since trying something like
<script>
const template = Handlebars.compile(#Html.Raw(Model.Template));
</script>
and
templateResult: template,
works as expected.
In the last example i pass the template from the model,
but not i need to pass it from the ajax response and achieve the same output.
There are multiple problems:
templateResult expects a callback function, but you are passing a compiled Handlebars template object. It's described here in the select2 docs. So, assuming that you already did the following in the right place:
var t = Handlebars.compile(...)
Then something like this would work:
templateResult: function(data) {
if (!data.id) return data.text;
return $(t({
name: 'example name',
vafm: 'example vafm',
email: 'example email'
}));
The template html must have one enclosing element, so put things in a <div></div>, for example
Your template is missing a <small> opening tag
So let's assume your server sends some JSON like the following. The template for every result is sent along and can be different for every result. Same goes for the template-specific data:
[
{
"id": 1,
"text": "Henry",
"data": {
"vafm": "1234",
"email": "henry#example.com"
},
"template": "<div>{{text}}<br><small>vafm: {{data.vafm}}</small></div><small>email: {{data.email}}</small>"
}, {
"id": 30,
"text": "Tesla Roadster",
"data": {
"price": "$200.000",
"color": "dark red"
},
"template": "<div>{{text}}<br><small>price: {{data.price}}</small></div><small>color: {{data.color}}</small>"
}
]
Together with something like this in your JavaScript, it should work:
$('#UniqueId').select2({
ajax: {
url: '/search/endpoint',
dataType: 'json',
processResults: function(data) {
/** Note: select2 expects "results" to be an array of objects, each containing
* at least "id" (becomes the value) and "text" (displayed text). I made the
* format from the server match that (plus added some more info), so that I don't
* need any conversions except for compiling the template. I do that with
* Array.prototype.map() in this case, but of course a for-loop would work too.
*/
return {
results: data.map(function(e) {
e["template"] = Handlebars.compile(e["template"]);
return e;
})
};
}
},
templateResult: function(el) {
if (!el.id) return el.text;
/* Note: "el" will be just like it came from the server, except for the
* modifications we applied in processResults. We can just pass "el" to
* the compiled template entirely and there, only pick what we need.
*/
return $(el["template"](el));
}
});

Can't get select2 to work with a json file

I am trying to get select2 to work with an external json-file:
The json-file looks like this (it is called data.json and is in the root directory of my Website):
{"laender":[
{
"Land" : "Ägypten",
"kurz" : "EG",
"Fahne" : "aegypten"
},
{
"Land" : "Andorra",
"kurz" : "AN",
"Fahne" : "andorra"
}
]}
The Javascript Looks like this:
$(document).ready(function($) {
function formatValues(data) {
return data.Land + ' ' + data.Fahne;
}
$('#countrySelect').select2({
ajax: {
dataType: "json",
url: "data.json",
results: function (data) {
return {results: data};
}
},
formatResult: formatValues
});
(As mentioned here: Select2 load data with Ajax from file).
The Output in HTML is a simple
<div id="countrySelect"></div>
But I can't get it to work. I tried so many things but nothing happens. Also I am rather new to json and Ajax.
Thanks for any help in advance!
Dietmar
your javascript code is for old version select2 below 4.0.0. if you using select2 4.0.0, then you must using processResult instead of result.
try to change these lines
results: function (data) {
return {results: data};
}
to like this
processResults: function (data) {
return {results: data};
}
for additional info, select2 4.0.0 doesn't support input hidden anymore. so, your #countrySelect must be select element rather than hidden input.
sorry my bad english
reference:
select2 4.0.0 ajax documentation
Your keys in json is:
"Land", "kurz", "Fahne",
but select2 in this case expect:
"id", "text"
to make: <option value="id"> text </option>
You should use map function:
processResults: function(data){
return {
results: $.map(data, function(smthg){
return { id: smthg.kurz, text: smthg.Fahne }
})
};
}
its example, i don't know which values You want use, and i use json like:
[
{"id_pr":"1252","pr":"aaa"},
{"id_pr":"1253","pr":"bbb"}
...
]
and it works, but
i didn't try:
{ laender: [
{"id_pr":"1252","pr":"aaa"},
{"id_pr":"1253","pr":"bbb"}
]}

AngularJs Multipart $http Request Issue

For some reason I can't get [object Object] out of the form. I'm using hte method found here:
http://badwing.com/multipart-form-data-ajax-uploads-with-angularjs/#comment-431
The JSON i'm sending is pretty complicated (sample):
{
"challenge_id": 262,
"priority": "0",
"cause_id": "29",
"timestamp": "2013-11-29 12:06:01",
"translations": {
"en": {
"name": "asdfgsfd",
"description": "sdfghfs"
}
},
"actions": {
"1": {
"type": "chek",
"step": "1",
"translations": {
"en": {
"description": "adsfas"
}
}
},
"2": {
"type": "chek",
"step": "2",
"translations": {
"en": {
"description": "fsdgsd"
}
}
}
}
}
My response looks like this:
Content-Disposition: form-data; name="challenge_json"
[object Object]
My request looks like this:
return $http.post( REQUEST_URL + '/ENDPOINT', {challenge_json:data}, {
transformRequest: function(data) {
console.log(data);
var fd = new FormData();
angular.forEach(data, function(value, key) {
fd.append(key, value);
});
console.log(fd);
return fd;
}
Im modifying the headers with a httpProvider configuration change. But have tried doing it in line and am getting the same result.
any help would be appreciated.
It seems you were close to the solution, but needed to unset the 'content-type' header in the options passed to $http, so that the xmlhttprequest object can add it automatically when it gets a formdata on its send method.
https://groups.google.com/d/topic/angular/MBf8qvBpuVE/discussion
see a playground here http://jsfiddle.net/Lv1n55db/1/
(providing FormData object directly and a no-op transform, or your way of providing a normal data object and transforming it to FormData in transformRequest is no significant difference, the key is in the headers option)
headers:{'Content-Type':undefined},
It may vary with differnt browsers and different angularjs versions too.
A more certain and stable approach, at least if you do not need file fields and such, could be to not use native FormData but implement the serialization to string yourself, as FormData polyfills do it.

AngularJS/Restangular indexed JSON data extraction

I've got and app that takes quote input (purity, weight, total), and it pushes to $scope.quote:
// Controller action //
$scope.quote.push({
total: ((($scope.karat * $scope.spot) * $scope.percentage) / 20) * $scope.estimatedWeight,
karat: $scope.karat * 100,
description: $scope.description,
actualWeight: $scope.actualWeight,
estimatedWeight: $scope.estimatedWeight,
percent: $scope.percentage * 100,
spot: $scope.spot
})
and
// Factory //
app.factory('quoteFactory', function() {
var quote = [];
var factory = {};
factory.getQuote = function () {
return quote;
};
return factory;
})
and the post/save upon quote completion
$scope.save = function() {
var now = $scope.getDate();
$scope.quote.push({
createdOn: $scope.getDate()
})
Restangular.all('quote').post($scope.quote).then(function(quote){
$location.path('#/scrap')
});
};
When trying to access the quote JSON for list or edit I can't access all the information needed because of the JSON structure.
{
"0": {
"total": 401.79040000000003,
"karat": 74,
"description": "Rings",
"actualWeight": 12,
"estimatedWeight": 11,
"percent": 80,
"spot": 1234
},
"1": {
"total": 560.7296,
"karat": 56.8,
"description": "Test",
"actualWeight": 22,
"estimatedWeight": 20,
"percent": 80,
"spot": 1234
},
"2": {
"total": 48.5625,
"karat": 92.5,
"description": "Testing",
"actualWeight": 80,
"estimatedWeight": 75,
"percent": 70,
"spot": 20
},
"3": {
"createdOn": "2013-11-26T21:26:42.253Z"
},
"_id": {
"$oid": "52951213e4b05f03172f14e7"
}
}
Each index represents a line item of the quote and the createdOn info. What I'm trying to figure out is if there is a way to be able to access all the line item information without having to call each individual index?
I've looked into some lodash/underscore, thought about restructuring the backend... Not really sure where to go from here.
Complete project code at github
Since there is not much details available as to how your backend works or is handling the data I am assuming the problem is with generating the JSON.
What I would do is change the way Angular posts the data to the server, for example:
the Save function:
$scope.save = function() {
var url = 'http:127.0.0.1:3000/url/you/send/your/data/to',
json = JSON.stringify($scope.quote);
$http({
method: 'POST',
url: url,
data: json,
headers: {
'Content-Type': 'application/json'
}
}).then(function(response) {
$location.path('#/scrap');
});
};
This will give you more control, and will make sure you control how the data gets turned into proper JSON, in this case using the .stringify() method of the JSON object.
I see from your comments that you are concerned with indexing; conventionally objects that sync with the server have a property id that represents their database id's NOT their client array index. This is a good way to keep the model data on the client a representation of the truth on your server side.
There are quite some libraries out there that help with this process client side, I would suggest - since you are using Angular already - reading into Angular Resource.
NOTE: if you want to support older browsers with the JSON.stringify() method, make sure you use Crockford's JSON2.js

The confuse about use jquery $.ajax to read javascript file

suppose I have a config javascript file:
window.Config = {};
Config.UI = {
"Area": {},
"Layer": {},
"Sprites": {},
"Audio": {}
};
Config.UI.Area = {
"prop": {
"uuid": {
"_type": "string",
},
"frame": {
"_type": "rect",
"_value": {
"x": "0",
},
"_aka": "frame"
},
"zIndex": {
"_type": "string",
}
},
then I want use $.ajax to read this file:
$.ajax({
url:'js/config.js',
success:function (data, textStatus) {
console.log(data);
}
})
the question is how can I get some key's value in the config,by use the data $.ajax return?
like the "Config.UI" or the 'uuid' in ui.area.prop?Or can I convert them to json?
Rather than use AJAX, why not just insert a script?
var script = $('<script>');
script.attr('type', 'text/javascript');
script.attr('src', 'js/config.js');
script.bind('load', function() {
// use window.Config
});
script.appendTo('head');
icktoofay has a good suggestion, and the issue with the jQuery.ajax call looks to be a missing dataType: 'script' option which will evaluate the response and should give you object access. You might want to look into jQuery.getscript() as well.
I find it very useful and powerful to store data on the server as javascript objects and read them using Ajax. And it is very easy to do. Let me give you an example from an educational application I have written.
This is an example table of contents file (l1contents.js) that I would store on the server:
{
title : "Lesson 1",
topics : [
{name : "Topic 1", file : "l1t1data.js" },
{name : "Topic 2", file : "l1t2data.js" },
]
}
This is the javascript code I use to process the file:
$.ajax({
url : contentsFileName, // would be set to 'l1contents.js'
dataType : 'text', // yes this is correct, I want jquery to think this is text
cache : false,
success: function(data) {
var contentsObj = eval('(' + data + ')');
var lessonTitle = contentsObj.title;
for (var i = 0; i < contentsObj.topics.length; i++) {
var topic = contentsObj.topics [i];
// process topic.name and topic.file here
}
}
});
Obviously, this is simplified, but hopefully you get the idea. I simply use eval to set the object. And note that I don't even need any javascript code defining the structure of contentsObj. (I, of course, do have extensive comments defining the structure of my objects, but they are simply comments, not code.)
if your json file contains json data than you can use parseJSON() , toJSON() method.
and another solution is use eval(), this conver json data to javascript object so you can easly get a value by giving key.

Categories