JSON result containing only one item - javascript

I'm likely missing something with json and javascript.
[{"commentText":"Testing 123","userPosted":"maxfridbe"},
{"commentText":"Testing 23","userPosted":"maxfridbe"}]
Sometimes I get multiple responses which works with this code:
function(data)
{
var sel = this;
jQuery.each(data,
function()
{
sel.append("<li>"+ this.userPosted+ "-" + this.commentText + "</li>");
});
};
Sometimes I only get one response which breaks the above code:
[{"commentText":"another test again welcom","userPosted":"maxfridbe"}]
I know this is because the response is being treated differently than a list.
Looking for the answer to this I get a bit of a runaround. Any solution would be greatly appreciated.

In the second example you provide, it seems to be an array with only one item, if it's like that, it should work, but I think that you're getting only a single object like:
{"commentText":"another test again welcom","userPosted":"maxfridbe"}
If it's a single object $.each iterates over the object properties.
You could check if your data variable is not an array using $.isArray, and if is not, you can wrap it into a single element array, so the $.each function will still work as expected:
//..
if (!jQuery.isArray(data)) data = [data]; // if isn't an array, wrap it
jQuery.each(data, function() {
sel.append("<li>"+ this.userPosted+ "-" + this.commentText + "</li>");
});
//..

I think you should user some optional parameters in your each() function:
function(data)
{
var sel = this;
jQuery.each(data,
function(i, item)
{
sel.append("<li>"+ item.userPosted+ "-" + item.commentText + "</li>");
});
};
using THIS keyword creates confusion in your case
Hope this helps

Playing around with CMS's solution made me realize that data was just a string somehow so:
if (!jQuery.isArray(data)) data = eval(data);
worked because then the data was an object. Not sure why when there are multiple results it does an eval for you.

Related

websql Insert statement in loop , data source - json

After hours of hit and trial this code has finally worked after looking at various posts for help. But i want someone to help me understand the function(i,dat) , what does this means ? Here is my full code below -
function get_assignedtasks_first_time(){
var jdata=$.getJSON( "http://45.114.246.107/quicktask/webservice/admtask.php?entdt=&entusr=SAURABH&company=&taskno=&status=&priority=&primary=", function( data ) {
db.transaction(function (tx) {
$.each(data, function(i, dat) {
tx.executeSql('INSERT INTO tasks (sno, taskdesc) VALUES("'+data[i]['SNO']+'", "'+data[i]['TASKDESC']+'")');
});
alert("completed");
});
});
}
The function $.each takes in two parameters. The first is the array being iterated over, and the second is a callback function to execute for each element in the array.
For each element in the array, $.each will execute this callback function with two arguments. The first argument (which you defined as i) is the index of the current element, and the second argument (dat) is the actual element you are looking at for each iteration.
For the function you defined, you are extracting the 'SNO' and 'TASKDESC' properties from each of the elements in the array. However, it looks like instead of using the dat parameter, which contains the current entry, you are using the original array (making your code a little bit more complicated to read).
Another way to implement the function might look like this:
function(index, element) {
// put these variables in quotes
var sno = "'" + element.SNO + "'";
var taskdesc = "'" + element.TASKDESC + "'";
// join these strings with commas
var values = [sno, taskdesc].join(',');
tx.executeSql("INSERT INTO TASKS (sno, taskdesk) VALUES(" + values + ")")
alert("inserted " + values);
}
In this case, we didn't need to use index at all since we are using the second parameter (the element being iterated over).

How can I only select some JSON objects?

Hi I have a script which parses a local JSON object (at the moment just to display a list).
function generateFamilySelect() {
var implantData = JSON.parse(localStorage.getItem("implantData"));
var implantFamilies = "";
$.each(implantData.implantFamilies, function( index, value ) {
implantFamilies += implantData.implantFamilies[index].familyDisplay + "<br />";
});
$("#holderForFamilySelect").html(implantFamilies);
}
and the JSON object:
{"implantFamilies":[
{"id":"1","familySelector":"aa","familyDisplay":"One","loadInitially":"1"},
{"id":"2","familySelector":"bb","familyDisplay":"Two","loadInitially":"1"},
{"id":"3","familySelector":"cc","familyDisplay":"Three","loadInitially":"1"},
{"id":"4","familySelector":"dd","familyDisplay":"Four","loadInitially":"0"},
{"id":"5","familySelector":"ee","familyDisplay":"Five","loadInitially":"0"},
{"id":"6","famiā€¦
At the moment, the list shows all of the elements. How can I modify this script to only show those with "loadInitially":"1"?
Also, a quick syntax question, I feel like the line
implantFamilies += implantData.implantFamilies[index].familyDisplay + "<br />";
could be written something like
implantFamilies += this[index].familyDisplay + "<br />";
but I can't get that to work...
The easiest is to use the Javascript Array.filter() method
// (or in your case, you get it from localstorage, but here's the data)
var myJson = {"implantFamilies":[
{"id":"1","familySelector":"aa","familyDisplay":"One","loadInitially":"1"},
{"id":"2","familySelector":"bb","familyDisplay":"Two","loadInitially":"1"},
{"id":"3","familySelector":"cc","familyDisplay":"Three","loadInitially":"1"},
{"id":"4","familySelector":"dd","familyDisplay":"Four","loadInitially":"0"},
{"id":"5","familySelector":"ee","familyDisplay":"Five","loadInitially":"0"}] };
//the array of implant families
var implantFamilies = myJson.implantFamilies;
//the filtering function. This is preferable to $.each
function implantFamiliesThatLoadInitially(implantFamily){
return implantFamily.loadInitially === '1';
}
//this is only the ones you want, (filtered by loadInitially property)
var loadInitiallyImplantFamilies = implantFamilies.filter(implantFamiliesThatLoadInitially);
The goal of the second part of your code is to build some html based on the data in the json, stored in teh variable implantFamilies. I will recommend Array.map() as an easier solution, than dealing with this. like before I am breaking this into multiple steps with comments so it is clear what is happening.
//your map function. You can make any html you want, like li's
function toImplantFamilyHtml(family){
return family.familyDisplay + '<br />'
}
//returns a plain string of html
var implantFamilyHtml = loadInitiallyImplantFamilies.map(toImplantFamilyHtml);
//jquery object you can use, or append to the DOM or whatever
var $implantFamilyHtml = $(implantFamilyHtml);
//append to DOM
$("#holderForFamilySelect").html($implantFamilyHtml);
working Fiddle: https://jsfiddle.net/mv850pxo/2/
the_5imian has provided a good answer to your first question, and you have determined the obvious alternate solution, given your current code.
As to your second question (this within jQuery.each()):
Within jQuery.each(), this is the value wrapped as an Object. value is the value of the array element at the current index, not the entire array. In other words, you don't use [index] on value or this within this context to get the current array element. For this code, value and this are the same because value is already an Object.
For what you want, you could just use value (Given that all elements of the array are already Objects, you could use this instead, but using value is a better habit to be in.):
$.each(implantData.implantFamilies, function( index, value ) {
if (value.loadInitially == "1") {
implantFamilies += value.familyDisplay + "<br />";
} else {
//do nothing
}
});
this is the value wrapped as an Object:
The following should show you what the values of value and this are within $.each(array,function(index,value){...});:
var myArray = ['zero','one','two','three','four','five'];
$.each(myArray, function(index,value){
console.log(index + ' value =',value);
console.log(index + ' this =',this); //this is the value wrapped as an Object.
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Well that just seems obvious now.
$.each(implantData.implantFamilies, function( index, value ) {
if (implantData.implantFamilies[index].loadInitially == "1") {
implantFamilies += implantData.implantFamilies[index].familyDisplay + "<br />";
} else {
//do nothing
}
});
How about the second part of my question?

jQuery command other than appendTo

I am trying to clear an LI tag's previous data.
Is there another command that will work other than appendTo?
Here is what my code currently looks like:
var obj = JSON.parse(data);
$.each(obj, function(index, item)
{
$('<li>').
text(item.datestamp+' - '+item.comment).
appendTo($('#pCodeComment'));
});
I asked a similar question not too long ago. I just want to know if there is another command other than appendTo that will clear out the previous data.
You should empty the list before you loop to populate it, then just continue doing what you are already doing.
var obj = JSON.parse(data);
$('#pCodeComment').empty();
$.each(obj, function(index, item)
{
$('<li>').
text(item.datestamp+' - '+item.comment).
appendTo($('#pCodeComment'));
});
And after optimizing a little bit:
var obj = JSON.parse(data); // i'm assuming `obj` is an array
var htmlToInsert = obj.map(function (item) {
return '<li>' + item.datestamp + ' - ' + item.comment + '</li>';
}).join('');
$('#pCodeComment').html(htmlToInsert);
Note: the above is vulnerable to XSS. See this so question for ways to fix it, or just use the original.
$.replaceWith()
might be what you are looking for, or as Kevin B pointed out
$.html()
replaceWith would need an element selected to replace. whilst html will populate a parent element to insert a new dom fragment into.

JavaScript & jQuery parse JSON in loop

Sorry about asking this, I can't get it to work even with looking at other questions...
I have a JSON output in "json.php", for example:
[
{"serverid":"1","servername":"Server One"},
{"serverid":"2","servername":"Server Two"}
]
I have a script, to grab the data & parse it into a variable
var servers;
jQuery.get('json.php', function(data) {
servers = JSON.parse(data);
jQuery('#servers').servers.servername
});
I have a div to output the results to:
<div id="servers"></div>
Whatever I try, I always get some kind of
"Uncaught TypeError: Cannot read property 'servername' of undefined" error.
I'd also like to look around the results, however I can't even get it to print atm.
Again sorry for another question like this
Don't you mean something like this? the jQuery object (which is a reference to your div) knows nothing about servername. Also, you'll need to iterate through the array of items in order to get them all:
servers = $.parseJSON(data);
$.each(servers, function(index, value) {
$("#servers").text($("#servers").text() + " " + value.servername);
});
Fiddle: http://jsfiddle.net/H2RC2/1/
The error message is all you need.
The jQuery('#servers') wrap the #servers div in the jQuery object. And this object has got no property such as servers.
Rather you could use:
var servers = JSON.parse(data);
var res = '';
for(var i = 0; i<servers.length; i++){
res = res + '<p>' + servers[i].servername +'</p>';
}
$('#servers').append(res);

Read from serialize to populate form

I did serialize() on my form and saved the string, is there any function which can populate values back to the form from serialized string?
Here is the updated version of Explosion Pills' answer with the additional suggestions in the comments applied:
$.each(serialized.split('&'), function (index, elem) {
var vals = elem.split('=');
$("[name='" + vals[0] + "']").val(decodeURIComponent(vals[1].replace(/\+/g, ' ')));
});
Check out http://phpjs.org/functions/unserialize:571
I recommend instead of serializing data for communication with javascript, you use JSON. PHP should have json_encode() and json_decode() to help with this, and javascript also has built in JSON handling functions, which you may not even need. For example, if $.getJSON gets a valid JSON string from the server, it will be transformed into a javascript object automatically.
EDIT: assuming you are talking about jQuery's $.serialize(), that I know of there's no function to undo this (I'm not even sure why that would ever be necessary..) but this should work:
$.each(serialized.split('&'), function (index, elem) {
var vals = elem.split('=');
$("[name='" + vals[0] + "']").val(vals[1]);
});
Based on previous answers, if you have checkbox or radio buttons:
$.each(serialized.split('&'), function (index, elem) {
var vals = elem.split('=');
var $elem = $formularioEquipo.find("[name='" + vals[0] + "']");
var value = decodeURIComponent(vals[1].replace(/\+/g, ' '));
if ($elem.is(':radio,:checkbox')) {
$elem.prop('checked', ($elem.val() === value));
} else {
$elem.val(value);
}
});

Categories