JavaScript to Handle REST JSON Feed - javascript

Trying to figure out the JavaScript syntax for handling JSON feed returned by a REST service. Suppose a random REST service (e.g. http://random.service/directory) is returning the following feed:
{
'firstName': 'John',
'lastName': 'Smith',
'address': {
'streetAddress': '21 2nd Street',
'city': 'New York'
}
}
and that I have a JSON parsing JS function (to parse the above feed) like:
function parseRESTFeed(json) {
...
}
How do I bridge the REST call of "http://random.service/hello" to parseRESTFeed(json) via JS?
Much Thanks!

If you use jQuery (and you should if you don't), then you can do it like this (ref):
$.getJSON('http://random.service/directory', null, function(data){
// And here you can do whatever you want with "data", no need to parse it
alert(data.firstName);
});
If you have some other way to get response from the service as string, again there is no reason to parse, since you can use javascript's eval. For example:
var myJSON = "{'firstName': 'John','lastNAme': 'Smith'}";
var data = eval('(' + myJSON + ')');
alert(data.firstName);

Related

Axios sends an array of strings instead of an array of objects

Axios sends an array of strings instead of an array of objects. I have an array of objects that contains data about the event. I'm trying to send a request to the server via axios, but I get a array of strings insteenter image description heread of objects at the output
let data = {
title: 'Game',
subject: 'Some subject',
date: ['01/01/2021','01/01/2021'],
years: ['1970', '1970'],
address: 'None',
ages: [
{
title: 'Men',
weights: [{page: 0, title: '60'}]
}
]
};
api.Create({
params: data
}).then(function (response) {
console.log(response.data);
})
.catch(function (err) {
console.log(err);
});
api response
try to:
console.log(JSON.parse(response.data))
What you get back from the server is string. you need to parse it.
When you send data to and from a server, it is sent as a 'serialized' string, usually JSON format
That's how server responses work
It turned out to be an incorrect request. I used GET to pass the object, instead of POST, so it converts it to a string. I want to notice that there is an evil community on this site.

Extra quotes in req.query object

I have a problem with extra quotes in req.query object. I'm using Angular.JS(1.5.8) with NodeJS(6.2.0).
So what i mean:
On client side I have simple REST api
.factory('Users', function ($resource) {
var Users = $resource("api/users/" + ":_id", { _id: "#_id" }, {update: {method: 'PUT'}, query:{ method: "GET", isArray: false }});
return Users;
})
And use it like this
return Users.query({a: 'some text', b: 10}}).$promise.then(function(results){
return results.users;
});
And all works fine, on server I'm get as results console.log('Query parsing - ', req.query); - Query - { a: 'some text', b: '10' }
But when I'm trying to send nested object:
Users.query({a: 'some text', b: {first: 10, second: 20}})
On server I have results with extra quotes and object not valid: Query - { a: 'some text', b: '{"first":10,"second":20}' }.
As result I cannot use it for mongoose queries. When I waited for {$text:{"$search":"admin"}} I'm recived {$text:'{"$search":"admin"}'}.
Can someone faced this problem before. Thanks for the help
JSON/Object to QueryString and back conversion has many many issues. Nesting, Arrays, "null", boolean values etc. You just encountered one.
Simplest solution is to JSON.stringify() objects as query string value:
url = 'www.example.com' + '/resource' + '?json=' + JSON.stringify(dataObject);
Browsers will automatically URL encode the JSON string. On other clients you may have to do it manually.
You can parse it back on server. For example this expressjs middleware:
app.use(function(req, res, next){
if(req.query.json){
try {
req.query.json = JSON.parse(req.query.json);
next();
}catch(err){
next(err);
}
}
});

Angular $http - How to access JSON result values

I have a $http request which returns an object of a user.
$scope.profile = $http.get('api/users/' + $stateParams.userId).success(function(data) {
console.log(data);
});
How do i actually assign for example a user.username to $scope.profileUsername?
Copied from the console...
Object
__v: 0
_id: "56a1832a36dc3d0e00c7aa3f"
aboutme: "<p>Im the Boss.</p>"
additionalProvidersData: Object
county: "waterford"
created: "2016-01-22T01:17:30.863Z"
displayName: "Chris"
firstName: "Chris"
gender: "male"
imageURL: "/modules/users/client/img/profile/saveme-placeholder.png"
profileImageURL: "../modules/users/client/img/profile/avatars/2/45.png"
provider: "local"
roles: Array[2]
updated: "2016-02-09T02:55:38.744Z"
username: "abcdef"
__proto__: Object
Try this.
$http.get('api/users/' + $stateParams.userId).success(function(data) {
$scope.profileUsername = data.username;
});
The return values of the $http methods are promises, not the data.
This is due to their asynchronous nature and the function you pass as a callback is only executed once the HTTP requests returns, so do anything you want to do with the data, you gotta do it in the callback function.
EDIT:
You could also do it like this
$http.get('api/users/' + $stateParams.userId).success(function(data) {
$scope.profile = data;
});
That way you can have all the data in one variable, assuming you need all of it.
In your templates you can then just access the properties with the dot notation (profile.username).
Should be
$http.get('api/users/' + $stateParams.userId).success(function(data) {
$scope.profile=data;
});
It should be accessible on views like {{profile.username}}

convert json object to serialized string for server side processing?

I'm trying to convert a returned json object into a serialized string that I can process further with some PHP server side code:
The returned object looks like this:
Object {id: "123456787654321", email: "some-email#gmail.com", first_name: "First", gender: "male", last_name: "Last"}
I can convert the object to a string with the following:
var paramString = JSON.stringify(response);
console.log(paramString);
// doesn't work
//var params = paramString.serialize();
How do I now convert the string to a serialized string that I can pass to my server with the following client side call:
I would expect something like this:
id=123456787654321&email=some-email#gmail.com&first_name...
My server side code:
$.post("/functions/test_functions.php", {params: params}, function(data) {
...
}, "json");
I handle the params array like this server side:
$vars = $_SERVER['REQUEST_METHOD'] === "GET" ? $_GET : $_POST;
$params = array();
isset($vars['params']) ? parse_str($vars['params'], $params) : null;
You can pass JSON-string to server and decode it with json_decode(). See http://php.net/manual/en/function.json-decode.php for details.
Unless there's a specific reason for stringifying, you don't actually need to. jQuery .post will handle the serialization for you, for example:
var response = {id: "123456787654321", email: "some-email#gmail.com", first_name: "First", gender: "male", last_name: "Last"};
$.post("/functions/test_functions.php", response, function(data) {
...
}, "json");
Will make a POST request like this:
/functions/test_functions.php
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Form Data: id=12345654321&email=some-email#gmail.com&first_name....

backbone populate collection from external json

Below is the current code structure I have in place for a collection that I have manually constructed. I have a json file on my server which I am now trying to load in and basically remove the manual one and construct a collection based on that data. Was wondering what would I possibly need to change below to my code to help accommodate this.
var Game = Backbone.Model.extend({
defaults: {
name: 'John Doe',
age: 30,
occupation: 'worker'
}
});
var GameCollection = Backbone.Collection.extend({
model: Game,
url: 'path/to/json',
parse: function(response) {
return response;
}
});
var GamesView = Backbone.View.extend({
tagName: 'ul',
render: function() {
//filter through all items in a collection
this.collection.each(function(game){
var gameView = new GameView({model: game});
this.$el.append(gameView.render().el);
}, this)
return this;
}
});
var GameView = Backbone.View.extend({
tagName: 'li',
template: _.template($('#gameTemplate').html()),
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
var gameCollection = new GameCollection([
{
name: 'John Doe',
age: 30,
occupation: 'worker'
},
{
name: 'John Doe',
age: 30,
occupation: 'worker'
},
{
name: 'John Doe',
age: 30,
occupation: 'worker'
}
]);
var gamesView = new GamesView({collection: gameCollection});
$(document.body).append(gamesView.render().el);
This is one of the many things to love about Backbone. I don't know what you are using for your backend, but you state that you have a json file on your server, hopefully a json file full of the models that should be in your collection. And now here is the magic code (drumroll please..):
var GameCollection = Backbone.Collection.extend({
model: Game,
url: 'path/to/json/on/external/server',
});
var gameCollection = new GameCollection();
gameCollection.fetch();
Not much to it, right? Of course there are several options you can add or change to a fetch, so check out the docs here: http://backbonejs.org/#Collection-fetch. Backbone uses jQuery.ajax() be default, so check out the docs here to see all of the options: http://api.jquery.com/jQuery.ajax/
You shouldn't need the custom parse in your collection unless your models on the server don't match your backbone models.
Things to know:
fetch is asynchronous. It takes time to talk to the server, and the rest of your javascript will move on and complete. You will probably need to at least add a callback function to the success option, which will be called when fetch is finished, and it is good to add something to error as well, in case something goes wrong. You can add data as a query string so that your backend can use it using the data option, the data has to be an object. Here is an example:
gameCollection.fetch({
data: {collection_id: 25},
success: function(){
renderCollection(); // some callback to do stuff with the collection you made
},
error: function(){
alert("Oh noes! Something went wrong!")
}
});
fetch should receive data as JSON, so your url should either exclusive return JSON or be set up to detect an AJAX request and respond to it with JSON.
Firstly you need to fetch it from server as RustyToms said. And the other consideration is how to force the collection view to render itself again once data collected from server, as muistooshort commented.
If you manipulating fetch or sync you'll need to do it multiple times when there are more than one collection in app.
Doing such is native with Marionette, but in plain Backbone you can mimic the method of Marionette's CollectionView and do such:
//For the collection view
var GamesView = Backbone.View.extend({
initialize: function({
this.listenTo(this.collection, 'reset', this.render, this);
});
// Others
});
Then, when collection data fetched from server, the collection will trigger a reset event, the collection view noticed this event and render itself again.
For more than one collections, you can extract the code into a parent object in app and inherit from that.
var App.CollectionView = Backbone.View.extent({
initialize: //code as above
});
var GamesView = App.CollectionView.extend({
//Your code without initialize
});
I know this is a bit old at this point, but wanted to answer for anyone else stuck on this.
The code seems to come from the tutorial found here: http://codebeerstartups.com/2012/12/a-complete-guide-for-learning-backbone-js/
I too re-purposed the demo app found in that tutorial and had trouble rendering using external data.
The first thing is that the data itself needs to be converted to valid JSON or else you'll get a .parse() error.
SyntaxError: JSON.parse: expected property name or '}' at line 3 column 9 of the JSON data
or
error: SyntaxError: Unexpected token n
In your data source file, object properties need to be surrounded by quotes. It should look something like this:
[
{
"name": "John Doe",
"age": 30,
"occupation": "worker"
},
{
"name": "John Doe",
"age": 30,
"occupation": "worker"
},
{
"name": "John Doe",
"age": 30,
"occupation": "worker"
}
]
Secondly, once it's clear the external data is loading, we need to get it to render. I solved this (perhaps ungracefully) by moving the render() command into the success function of your gameCollection.fetch().
gameCollection.fetch({
success: function(collection, response, options) {
console.log('Success!! Yay!!');
$(document.body).append(gamesView.render().el);
},
error: function(collection, response, options) {
console.log('Oh, no!');
// Display some errors that might be useful
console.error('gameCollection.fetch error: ', options.errorThrown);
}
});
There are certainly better ways to accomplish this, but this method directly converts the code learned in the tutorial into something that works with external data.

Categories