Retrieving escaped JSON string from PHP webservice in javascript - javascript

I'm trying to retrieve some HTML to be inserted into a web page from a web service, I have a database of HTML which relates to different applications so i'm selecting the ID of the application and returning them in JSON to the javascript front end, the problem i'm getting is the first two numeric values get parsed fine, but the CSS/JS/HTML elements don't - i'm guessing its to do with the way the string is escaped but i'm not sure how to handle it?
[{"id":"1","machine_id":"1","CSS":"<link rel=\"stylesheet\" type=\"text\/css\" href=\"newcss.css\">","JavaScript":"<script src=\"js\/SlotMachine.js\" type=\"text\/javascript\"><\/script>,<script src=\"js\/jquery-1.11.1.min.js\" type=\"text\/javascript\"><\/script>","HTML":"<div class=\"outer_container\">\n <div class=\"reelcasing\">\n <canvas id=\"reel1\" width=\"150\" height=\"400\"><\/canvas>\n <\/div>\n <div class=\"reelcasing\"> \n <canvas id=\"reel2\" width=\"150\" height=\"400\"><\/canvas>\n <\/div>\n <div class=\"reelcasing\">\n <canvas id=\"reel3\" width=\"150\" height=\"400\"><\/canvas>\n <\/div>\n <input type=\"button\" id=\"start\" class=\"start_button\" value=\"Press Start\">\n <\/div>","rollSpeed":"25","rollIncrement":"20"}]
Then i'm doing:
$http({
method: 'GET',
url: 'http://localhost/api/machine/get/' + machineId
}).success(function(data){
$scope.machineDetails = data;
// Debugging
for(machine in data){
alert(machine.id);
}
}).error(function(){
alert("Unable to retrieve slot machine information.");
});
};
UPDATE
To clarify the values from the JSON get read in except where they've got the complex html, for example that example returns:
machineDetails: [
0: {
id: 1
machine_id: 1
CSS:
JavaScript: ,
HTML:
Edit:
Ok well its odd if I step through the data using...
angular.forEach(data, function(data, key){
console.log(data.CSS);
});
It gives the correct values however if I do:
$scope.machineDetails = data;
It fills in the ID and machineID but doesn't put any of the HTML stuff in, its not a massive issue but i'd like to know why it won't store it in scope?

Related

how to print array object array in html using angualrjs

I am trying to take data from a movie API (TMDB API) and want to display the details of the movie in my html view page.
I got the response from the API but i cannot figure out the way to handle the response that is in array of an object array.
This is my response
{
"page":1,
"total_results":1,
"total_pages":1,
"results":
[{
"vote_count":779,
"id":20453,
"video":false,
"vote_average":7.7,
"title":"3 Idiots",
"popularity":1.963226,
"poster_path":"\/wbE5SRTZFtQxgj2nIo4HJpQDk0k.jpg",
"original_language":"hi",
"original_title":"3 Idiots",
"genre_ids":[18,35,10749],
"backdrop_path":"\/6LnwpadKFRrqam7IfBAi3lNTz6Y.jpg",
"adult":false,
"overview":"In the tradition of “Ferris Bueller’s Day Off” comes this
refreshing comedy about a rebellious prankster with a crafty mind anda
heart of gold. Rascal. Joker. Dreamer. Genius... You've never met a
college student quite like \"Rancho.\" From the moment he arrives at
India's most prestigious university, Rancho's outlandish schemes turn
the campus upside down—along with the lives of his two newfound best
friends. Together, they make life miserable for \"Virus,\" the
school’s uptight and heartless dean. But when Rancho catches the eye
of the dean's sexy daughter, Virus sets his sights on flunking out the
\"3 idiots\" once and for all.",
"release_date":"2009-12-23"
}]
}
I want to display overview and other details that is in results in my html page using angularjs but i cannot figure out how to do that?
This is my js and html code snippet. Where i try this with another API but now it got private so i have to change the API.
function getItems(){
$http({method:'GET',url:"https://api.themoviedb.org/3/search/movie?api_key=9a1750d469929884b1c959126ec22c83&query=" + $scope.search})
.then(function (response) {
// body...
$scope.movies = response.data.results;
console.log(response.data.results);
});
<div class="movie-details col-sm-8" >
<ul class="details">
<li><img ng-src="{{movies.Poster=='N/A' && 'http://placehold.it/150x220&text=N/A' || movies.poster_path}}" class="movie-poster thumbnail"><a class="movie-title" href="http://www.imdb.com/title/{{movies.imdbID}}" target="_blank">{{movies.original_title}}</a>, {{movies.Year}} <span class="reviews">Reviews | Add your own review</span></li>
<li><span>Released On: </span>{{movies.results}}</li>
<li><span>Runtime: </span>{{movies.Runtime}}</li>
<li><span>Genre: </span>{{movies.Genre}}</li>
<li><span>Director: </span>{{movies.Director}}</li>
<li><span>Writers: </span>{{movies.Writer}}</li>
<li><span>Actors: </span>{{movies.Actors}}</li>
<li>{{movies.overview}}</li>
<li><span>Language: </span>{{movies.Language}}</li>
<li><span>Country: </span>{{movies.Country}}</li>
<li><span>Awards: </span>{{movies.Awards}}</li>
<li><span>IMDB Ratings: </span>{{movies.imdbRating}}</li>
</ul>
<br>
<div>
<a class="links" href="https://www.youtube.com/results?search_query={{movies.original_title}}" target="_blank">Watch Trailers!</a>
|<a class="links" href="https://subscene.com/subtitles/title?q={{movies.Title}}&l=" target="_blank">Get Subtitles!</a>
|<a class="links" href="http://www.amazon.in/s/ref=nb_sb_noss_1?url=search-alias%3Ddvd&field-keywords={{movies.Title}}" target="_blank">Buy Online!</a>
</div>
</div>
You have to use ng-repeat in order to show data in your html, further correct the property names that you bind on html. (for example: results to release_date)
(see this screenshot of console log data)
Sample DEMO :
var myApp = angular.module('myApp', []);
myApp.controller('ExampleController', ExampleController);
function ExampleController($scope, $http) {
function callapi() {
$http({
method: 'GET',
url: 'https://api.themoviedb.org/3/search/movie?api_key=9a1750d469929884b1c959126ec22c83&query=3%20idiot'
}).then(function(response) {
console.log(response.data.results[0]);
$scope.moviesData= response.data.results;
})
}
callapi();
}
<script src="https://code.angularjs.org/1.5.2/angular.js"></script>
<div ng-app="myApp" ng-controller="ExampleController">
<ul ng-repeat="movies in moviesData">
<li><span>Released On: </span>{{movies.release_date}}</li>
<li><span>Runtime: </span>{{movies.Runtime}}</li>
<li><span>Genre: </span>{{movies.Genre}}</li>
<li><span>Director: </span>{{movies.Director}}</li>
<li><span>Writers: </span>{{movies.Writer}}</li>
<li><span>Actors: </span>{{movies.Actors}}</li>
<li>{{movies.overview}}</li>
<li><span>Language: </span>{{movies.original_language}}</li>
<li><span>Country: </span>{{movies.Country}}</li>
<li><span>Awards: </span>{{movies.Awards}}</li>
<li><span>IMDB Ratings: </span>{{movies.imdbRating}}</li>
<hr>
</ul>
</div>
It looks like you are not using the results exactly as you should be. For instance you have movies.results but you already set $scope.movies to your return results properties.
Make sure that you are using the properties within the results property that you set movies to.
For example you could access the overview by calling {{movies.overview}} in your HTML

unexplained undefined string displayed on my website. not sure how to get rid of it

I have a undefined string being displayed on my page and i have no idea why it is their besides the function that is probably causing it, i only know this from displaying allot of console errors to locate the problem.
I believe that Mustache is doing this somehow when i call on templates.
"
undefined
"
The question is how do i get rid of this undefined string being injected in my page. Any help would be much appreciated.
Code:Function that is being called that is somehow or reason displaying a undefined string in my div
getProjects: function(){
portfolio.topOfPage();
var request1 = $.ajax({
url: "js/projects.js",
dataType:'json',
cache: true,
}).then(function(response){
var data = response.projects;
var template = $('#projects_tmp').html();
var projects;
$.each(data, function(key,val){
console.log("Key: "+key+", Value: "+val);
projects += Mustache.to_html(template, val);
});
return projects;
});
My mustache template:
<script id="projects_tmp" type="text/template">
<div class='small-6 medium-3 large-2 columns left thumb {{{genre}}}' data-id='{{{id}}}'>
<div class='project'><figure><img src='{{{largePic}}}' alt='' />
<figcaption class='caption'><span>{{genre}}</span></figcaption class='caption'></figure></div>
</div>
</div>
</script>
Problem is your projects variable should have a default value of '', in your getProjects method when you are doing projects += it is adding undefined value which comes by default.
I see 3 </div> and just 2 <div> in your code posted above. Not sure if that might be the issue.

too much HTML in an ajax script?

I read from this page that appending a lot of elements is bad practice and I should build up a string during each iteration of the loop and then set the HTML of the DOM element to that string. Does the same go for using too much HTML in the loop?
I have an AJAX script that parses JSON data. It requires adding data to different existing elements, like this:
$.ajax({
url: "url",
success: function (data) {
$(data.query.results.json.json).each(function (index, item) {
var title = item.title, // A,B,C or D
age = item.age,
background = item.background,
ingredient = item.Ingredient;
$('.'+ title+'_ingredient').html(''+ingredient+'')
$('.'+ title+'_age').html(''+age+'')
$('.'+ title+'_background').html(''+background+'')
});
},
error: function () {}
});
HTML:
<div class="A_ingredient"></div>
<div class="B_ingredient"></div>
<div class="C_ingredient"></div>
<div class="D_ingredient"></div>
<div class="A_age"></div>
<div class="B_age"></div>
<div class="C_age"></div>
<div class="D_age"></div>
<div class="A_background"></div>
<div class="B_background"></div>
<div class="C_background"></div>
<div class="D_background"></div>
Is it necessary to build up a string first? If so, can you show me how to do that?
It is purely about the time it takes to process calls to html() so they simply recommend you reduce the number of calls. In this case you could build them once in a loop then sets the div html once for each.
Update:
Based on your update, aside from all the extra trailing quotes you don't need to add (a string is a string is a string), your code is fine as is. You only hit each item once.
e.g.
$.ajax({
url: "url",
success: function (data) {
$(data.query.results.json.json).each(function (index, item) {
var title = item.title, // A,B,C or D
age = item.age,
background = item.background,
ingredient = item.Ingredient;
$('.'+ title+'_ingredient').html(ingredient);
$('.'+ title+'_age').html(age);
$('.'+ title+'_background').html(background);
});
},
error: function () {}
});
Note: If your item properties (Age, Background, Ingredient) are simple values (not objects or arrays), yo do not need the leading ''+s either.
Previous
Assuming you actually want to concatenate the results (you are only keeping the last ingredient at the moment), you could do something like this:
e.g.
$.ajax({
url: "url",
success: function (data) {
var ingredients = '';
$(data.query.results.json.json).each(function (index, item) {
var title = item.title;
var ingredient = item.Ingredient;
ingredients += ingredient;
});
$('.aclass').html(ingredients);
$('.bclass').html(ingredients);
$('.cclass').html(ingredients);
$('.dclass').html(ingredients);
},
error: function () {}
});
Which can be reduced to:
$('.aclass,.bclass,.cclass,.dclass').html(ingredients);
The contents of each div are identical in your example, so you only need a single string.
In this instance you would probably need some form of delimiter between ingredients, but your example is too vague.
e.g.
ingredients += ingredient + '<br/>';
In your example, you're setting the HTML on many different document elements.
If they're grouped in some way, for example all in a Div with ID #Container, you could build a string of the HTML and set the content of the whole Div at the end of it, something like this:
$.ajax({
url: "url",
success: function (data) {
var sHTML="";
$(data.query.results.json.json).each(function (index, item) {
var title = item.title,
background = item.background,
ingredient = item.Ingredient;
// not sure what your actual HTML is (div/span/td etc) but somethign like this?
sHTML+="<div>"; // an opening container for this item
sHTML+='<div class="'+title+'_ingredient">'+ingredient+'</div>')
sHTML+='<div class="'+title+'_age">'+title+'</div>')
sHTML+='<div class="'+title+'_background">'+background+'</div>')
sHTML+="</div>";
});
$("#Container").html(sHTML);
},
error: function () {}
});
Note I haven't tested this code, but you see the principal hopefully.
That is, build a string of the HTML then set one element at the end with the content.
I have done this a lot in a recent project and haven't seen any speed issues (maybe 50 'items' to set in my case).
HTML will initially look like this :
<div id="container">
</div>
Then end up like this (2 x items in this example) :
<div id="container">
<div>
<div class="<sometitle1>_ingredient">ingredient 1</div>
<div class="<sometitle1>_age">age 1</div>
<div class="<sometitle1>_background">background 1</div>
</div>
<div>
<div class="<sometitle2>_ingredient">ingredient 2</div>
<div class="<sometitle2>_age">age 2</div>
<div class="<sometitle2>_background">background 2</div>
</div>
</div>
subsequent calls will replace the element's content with new values, replacing the old items.
Building a string is, I would imagine, less processor-heavy than setting the html() on lots of elements individually. Each time you use html() I'm guessing that the browser has to go some way towards working out any knock-on effects like expanding the width of an element to accomodate it or whether events will still work as they did, etc - even if actual rendering is only run at the end of the process. This way you use html() once, although what you're setting is more complex.
Hope this helps.

Process data-attributes: how to seralize

I'm trying to create and HTML chart with a jquery plugin and I'm using HTML5 data attributes to pass data from my rails app to jquery function.
My html, after the ruby hash conversion, is something like this:
<div class="chart" data-contents-01="0" data-contents-02="1" data-contents-03="3" data-contents-04="0" data-contents-05="0" data-contents-06="0" data-contents-07="0" data-contents-08="0" data-contents-09="0" data-contents-10="0" data-contents-11="0" data-contents-12="0" data-contents-13="0" data-contents-14="0" data-contents-15="0" data-contents-16="0" data-contents-17="0" data-contents-18="0" data-contents-19="0" data-contents-20="0" data-contents-21="0" data-contents-22="0" data-contents-23="2" data-contents-24="1" data-contents-25="4" data-contents-26="0" data-contents-27="0" data-contents-28="0" data-contents-29="2" data-contents-30="2" data-contents-31="0" id="chart_2" style="padding: 0px; position: relative;">
I have a lot if data-contents-xx and I must convert this data to an array of array.
My function take data as:
var contents = [
[x, y],
[x,y]
];
so I must process my data attributes to have an array of array, where each sub-array is a couple of data-contents-x
How can i serialize my data attribute?
The JQuery method .data() will pull all data objects into an array of key: value pairs. With your element names:
$('.chart').data();
For example, given:
<div class="chart" data-foo="1" data-bar="2"></div>
Use:
var data = $('.chart').data();
for(var i in data){
console.log("data attribute - " + i + ":" + data[i]);
}
Here's the fiddle: http://jsfiddle.net/WVfSg/260/
When playing with your code in the fiddle, it doesn't work. However, when I get rid of the second hyphen, it works as expected.

How to integrate JsonResult with Ajax forms and javascript

Using MVC4, how would I process the return value of a JsonResult action in an Ajax form?
All of the examples I was able to locate deal primarily with an html result (ActionResult).
I know this question is poorly framed, missing code and such, but I plan on providing my experience as the answer. Hopefully between this question and the answer there will be some good content.
In an ASP.net controller (C#) you can return a json result as follows (hope you already know it).
[httppost]
public ActionResult MyAction(){
//this is the most amazing content
return Json(new
{
MyResult = "ok",
MyData = "This is some string data!"
});
}
Its not clear for me what you expect from the answer or I am not sure whether this is what you need as an answer, but hope it will be helpful.
If you are using jquery ajax, you can access the controller and get the json results it returns.
$.ajax({
type: "POST",
URL: "/MyController/MyAction",
dataType: "text"
})
.success(function(data){
var dataobj = $.parseJSON(data);
var result = dataobj.MyResult;
var msg = dataobj.MyData;
});
When you are using return new Json(); the server response is of ContentType application/json. But, to use Jquery's parseJSON function correctly, you need to pass the json to the function as a string, otherwise it do not parse it correctly. So, to get the json result as a string or 'text' you need to add dataType: "text" as an option to $.ajax{}. Then the server returns its response as plain text and you can parse json using jquery's parseJSON function. It will return a dynamically created object which includes data returned as json. So you can access those data using the names included in the json string.
Hope this will be helpful somewhat.
So most examples/tutorials on the web will instruct you to return a view via your HttpPost action method. When doing this you would set the 'UpdateTargetId' and InsertionMode properties on the AjaxOptions object.
But if you want to return data and work with it via javascript, the above method falls short.
Rather, you will need to set the OnSuccess method of the AjaxOptions object.
As you can see from the documentation, OnSuccess contains zero helpful information. To use it correctly you need to provide the name of a javascript function available on the current page. This will be used callback-style so make sure you use the appropriate syntax for your use case.
Here's a little demonstration:
Controller methods:
<HttpGet>
Function AjaxIndex() As ActionResult
Dim model As AjaxFormModel = New AjaxFormModel
' AjaxFormModel is a custom class. Architect it as you see fit.
Return View(model)
End Function
<HttpPost>
Function AjaxIndex(ByVal model As AjaxFormModel) As JsonResult
Dim result As AjaxFormResult = Nothing
' AjaxFormResult is a custom class. Fill it in with properties that make sense for you. I personally include .MessageType and .Payload properties.
' TODO: be sure you spin up a new object to pass to the `JsonResult`.
Return New JsonResult With {.Data = result, .JsonRequestBehavior = JsonRequestBehavior.AllowGet}
End Function
Html
Using Ajax.BeginForm("AjaxIndex", "Bootstrap",
routeValues:=Nothing,
ajaxOptions:=New AjaxOptions With {.HttpMethod = "POST",
.OnSuccess = "updateAjaxForm"},
htmlAttributes:=Nothing)
#<text>
<div class="row">
<div class="col-sm-12" id="UnknownError_message">
</div>
</div>
<div class="row">
<div class="col-md-12">
<input type="text" name="Name" />
<div id="Name_message"></div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<input type="submit" class="btn btn-default" value="Save" />
</div>
</div>
</text>
End Using
javascript / jQuery
<script type="text/javascript">
function updateAjaxForm(data) {
//data is a fully reconstituted javascript object at this point. Thank you MVC!
var messageElement = $('#UnknownError_message');
switch (data.MessageType) {
case 0: // Error message
messageElement.html('Error: ' + data.Message);
break;
case 1: // Textual message
messageElement.html('Info: ' + data.Message);
break;
default:
messageElement.html('Unforseen Error.');
}
}
</script>

Categories