There seems to be a few questions around this, but I can't seem to find a conclusive answer.
I've created a WCF JSON web service that returns perfect JSON and this has been clarified using jsonlint.com. The web service returns an array (List< myresults>) and this seems to format the JSON with square brackets, like so:
[{"Image":"http://www.mywebsite/myimage.jpg"}]
Parsing the JSON on the iPhone platform seems to handle the backslashes fine, but it does not play nice with the square brackets - I had to manually remove these using this:
[str stringByReplacingOccurrencesOfString:#"[" withString:#""]; //(for each bracket)
However, I would also like to consume the same JSON in an HTML webpage using jquery and it seems I am faced with the same issue. Surely there is a more appropriate way to deal with these annoying square brackets?
I'd really appreciate if someone could post an easy way to handle the brackets - either removing them from the web service, or in my javascript code.
Thanks!
If it helps, my Javascript is as follows:
$.getJSON(urlToMyWebService, function(data) {
var items = [];
$.each(data, function(key, val) {
items.push('<li id="' + key + '">' + val + '</li>');
});
$('<ul/>', {
'class': 'my-new-list',
html: items.join('')
}).appendTo('body');
});
The square brackets just indicate an array. As you noted, since you're returning an array, it'll have the square brackets.
You'll need to have an array on the JavaScript/Objective C side as well, that's all.
First things first ids in HTML cannot start with numbers, so using key as id for your li is invalid. Second your JSON list contains objects with Image property so you probably want this:
$.each(data, function(key, val) {
items.push('<li id="li_' + key + '">' + val.Image + '</li>');
});
and here's a live demo.
Related
I used Google Tag Manager to create a custom data level variable to get the content of an ajax form. The result is in the attributes.response that looks like:
response:"{\"current_url\":\"https:\\/\\/domainname.com\\/ +
"manufacturer\\/category\\/model-number\\/\",\"h" +
"tml"\":{\"cart_status_528\":\"\\n <div id=\\\"s" +
...
"<a href=\\\"https:\\/\\/domainname.com\\/manufacturer" +
"-name\\/long-store-category-name\\/model-number-x\\/\\" +
"\" class=\\\"ty-product-notification__product-name\\\"" +
">PRODUCT-NAME THAT I WANT<\\/a>\\n " +
...
" <p><\\n more escaped html content +
}"
I am trying to extract/parse the attribute.response to retrieve the PRODUCT-NAME text. I have tried the following which matches in regexr. But, GTM keeps complaining there is an error in my javascript at the double quote symbol. What am I missing? Or is there a cleaner way to retrieve the text? Thanks
function() {
var regex = (?<=product-name(.|\n)*">)(.*)(?=<\\\\\/a);
var attributesResponse = {{attributes.response}};
if(regex.test{{attributesResponse}}
var ProductAddedToCart = regex.exec(attributesResponse)[1];
return ProductAddedToCart;
}
return false;
}
First of all, please read the top answer here: RegEx match open tags except XHTML self-contained tags
Secondly, your JS has many problems. Even the SO code highlighter indicates it. See some examples of how regex is used in JS.
The proper way to solve your task, however, would be adding a dataLayer push with the proper response details neatly stored in a dataLayer object. You would normally ask your front-end developers to add a push in their response callback. It should be trivial for them to tackle. You can read more on DL here.
I do an ajax call to a script that returns data. I see the data in firebug and it is correct. When the data comes back I do a sort and it works too. I see in firebug the object is sorted the way I want. After the sort I try to access a key/value pair. I see in firebug that the key/value I want is in the object. When I try to use the object key/value to assign to a var it is undefined. I'm trying to aggregate repeating data. If I'm not using the best way to do it, please help me with a better method.
data sample
coreDate "060115"
coreType "asterisk_11"
fileName "/var/www/html/Cores/gdb.hamid.asterisk.060115"
jid "hamid"
code
$.when (
$.ajax( {
type:"GET",
url: 'cf.php',
dataType: 'json',
timeout: 120000,
})
)
.done(function(coreInfo) {
coreInfo.sort(function(a,b) { return a.coreType > b.coreType } );
var coreStats={};
coreStats.numOfCores=0;
coreStats.numOfCoreType=0;
coreStats.prevCoreType=coreInfo.coreType;
// for some reason coreInfo.coreType is not defined. The coreInfo object exists and coreType is there. I tried this.coreType but is undefined.
$.each(coreInfo, function() {
coreStats.numOfCores++;
if (coreStats.prevCoreType != this.coreType) {
// This works. why do I have to access this.coreType instead of coreInfo.coreType?
$('#list > tbody:last-child').append('<tr><td><a href="'+this.fileName+'">'+this.coreType+'</td><td>'+coreStats.numOfCoreType+'<br>core</td><td>jid</td></tr>');
coreStats.numOfCoreType=0;
}
coreStats.numOfCoreType++;
coreStats.prevCoreType=this.coreType;
// setting prevCoreType works here
});
$('#cores').html("<h1>"+coreStats.numOfCores+"</h1><br>Core Files");
})
.fail(function() {
});
From your code and description, it sounds like coreInfo is an array of objects, is that right? If it were an object, it wouldn't have a sort() method and your code would stop right there.
If it's an array, it doesn't have a property like coreInfo.coreType. Each element of the array is an object with coreType and other properties. That's why you are able to access this.coreType inside the $.each() callback. $.each() iterates through the array, element by element, and passes each individual element into the callback.
Where it looks like you're seeing coreInfo.coreType in Firebug outside the $.each(), I suspect that what you're actually seeing is coreInfo[0].coreType, i.e. the first element of the array.
To help keep track of whether a variable is an array or not I strongly suggest giving arrays names that reflect this fact: either a plural word, or add List or Array to the name, or something. A name like coreInfo sounds like a singular item. I would call the array coreList, coreArray, or simply cores. Personally I like plural words for brevity: cores for the array of core info, core for an individual element in that array.
This way when you see cores.coreType or coreList.coreType or coreArray.coreType it will look wrong.
BTW for much more readable code, I suggest never using this in a $.each() callback. Instead, use named parameters.
$.each( coreInfo, function( i, core ) {
coreStats.numOfCores++;
if( coreStats.prevCoreType != core.coreType ) {
$('#list > tbody:last-child').append(
'<tr>' +
'<td>' +
'<a href="' + core.fileName + '">' +
core.coreType +
'</a>' + // MISSING IN ORIGINAL
'</td>' +
'<td>' +
coreStats.numOfCoreType +
'<br>core' +
'</td>' +
'<td>' +
'jid' +
'</td>' +
'</tr>'
);
coreStats.numOfCoreType = 0;
}
coreStats.numOfCoreType++;
coreStats.prevCoreType = this.coreType;
});
Note that there was a missing </a> in your markup in the code above. It's much easier to spot an error like this if you indent the markup strings in the same way that you might indent raw HTML code, instead of cramming it all onto one line.
A minor point: You don't need to wrap $.ajax() inside $.when(). $.ajax() returns a Promise that you can use directly.
You don't need the code that computes coreStats.numOfCores. You can simply use the length property of the array. If you follow my suggestion to call the array cores you could do this:
$('#cores').html( "<h1>" + cores.length + "</h1><br>Core Files" );
Finally, your sort callback function has a bug and will not sort the array properly. It may have worked in a simple test case, but it will fail to sort other arrays. It has to handle all three cases: <, ==, and > and return an appropriate value for each case, perhaps like this:
coreInfo.sort( function( a, b ) {
return(
a.coreType < b.coreType ? -1 :
a.coreType > b.coreType ? 1 :
0
);
});
To verify my assumptions, can you post an example of your actual JSON data, not a formatted table?
I have the following javascript:
tr.append("<a href='add_widget.html?id=" + data[i].id + "&pg=" + data[i].page_number + "&dest=" + data[i].dest + "&name=" + data[i].name.replace("'","\\'") + "'</a><button class='btn btn-xs btn-primary'>Edit</button> </td>");
The code in question has to do with the name field.
If I have a name like "John Doe" when I click on the hyperlink created by the above javascript, the new page's querystring has the full name.
However, if I try to pass a name like "John's stuff", the above logic creates a query string variable that looks like this:
&name=John\
How can I change the above code so that the entire string "John's stuff" is passed to the add_widget.html page?
Thanks.
replace("'","%27")
try http://meyerweb.com/eric/tools/dencoder/ it's an online URL encoder/decoder.
When you're trying to "protect" characters, you have to keep in mind what you're protecting them from. In this case, there are two interpreters you have to worry about:
You're building HTML, so you have to worry about the HTML parser;
You're building a URL, so you have to worry about how the browser and the server will parse the URL.
To deal with the first problem, you can replace the quotes with the HTML entity equivalent ('). To deal with the second, you can use encodeURIComponent().
I think you'd want to do the encodeURIComponent() call first, to avoid having the HTML entity notation get messed up. The entity notation will be gone after the HTML parser is finished with the string anyway:
function qEncode(str) {
return encodeURIComponent(str).replace(/'/g, "'");
}
To use that:
tr.append("<a href='add_widget.html?id=" +
qEncode(data[i].id) + "&pg=" +
qEncode(data[i].page_number) + "&dest=" +
qEncode(data[i].dest) + "&name=" +
qEncode(data[i].name) +
"'</a><button class='btn btn-xs btn-primary'>Edit</button> </td>"
);
Note that you could also encode double-quote characters too.
A totally different way of working around this problem would be to build the DOM content with DOM APIs. By doing that, you'd completely avoid the HTML parser, and you'd just need encodeURIComponent().
You need to think, what will be interpreting my code, so what do I need to escape for?
Your code will be interpreted by the HTML Interpreter in the browser
Your code will be interpreted as a URI
This means you need to escape/encode them in reverse order. Luckily JavaScript provides a URI encoder as encodeURIComponent, but it doesn't provide a HTML one (probably as we have DOM Methods) but it isn't too hard to implement for important characters, e.g.
function html_encode(str) {
var re_chars = /[<>'"]/g;
function replacer($0) {
return '&#' + $0.charCodeAt(0) + ';'
}
return str.replace(re_chars, replacer);
}
// example follows
html_encode('<foo bar="baz">'); // "<foo bar="baz">"
So for you,
attrib_value = html_encode(/* ... + */ encodeURIComponent(data[i].name) /* + ... */ );
For completeness,
function html_decode(str) {
var re = /&(?:#\d{1,3}|amp|quot|lt|gt|nbsp);/g, // notice extra entities
d = document.createElement('div');
function replacer($0) {
d.innerHTML = $0;
return d.textContent;
}
return str.replace(re, replacer);
}
// and an example
html_decode('<foo bar="baz">'); // "<foo bar="baz">"
Using escape(data[i].name) instead of data[i].name.replace("'","\\'"), will solve your problem.
Im looking for a simple script to convert JSON objects to Javascript objects, specifically being able to make an ajax call in jQuery and then convert all of the JSON that comes back into Javascript objects for me.
I've used the mapping plugin in KnockOut.js: https://github.com/SteveSanderson/knockout.mapping/tree/master/build/output
Which nicely takes my JSON result and creates the relevant objects in knockout.
Anything currently exist to do this without knockout?
jquery automatically does this for you.
from the JQuery documentation for getJSON:
$.getJSON('ajax/test.json', function(data) {
var items = [];
$.each(data, function(key, val) {
items.push('<li id="' + key + '">' + val + '</li>');
});
$('<ul/>', {
'class': 'my-new-list',
html: items.join('')
}).appendTo('body');
});
Just specify the dataType setting as 'json' in the $.ajax call, or use the $.getJSON method, and the JSON result will automatically be parsed into a Javascript object.
I'm guessing here, but if you want to convert them into already defined javascript objects you need the second argument in the JSON.parse function. Check MDN's documentation https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/JSON/parse.
Very simple example.
JSON.parse(json,function(prop,val){
if(prop==='objName'){
new myObj(val);
}
});
For use in JQUERY: http://api.jquery.com/jQuery.parseJSON/
For use in simple JS: https://github.com/douglascrockford/JSON-js (look at json.js or json2.js)
Knowing that it's well-formed:
var myObject = eval('(' + myJSONtext + ')');
I am not quite adept in maneuvering jQuery, and it came to a point that I need to debug a program that was passed down from me without a documentation.
I have this var a, an object, that I really want to know the content of its collection. In my mind I need a function like foreach() in PHP to iterate over this object variable. Upon researching I end up in using jQuery.each(). Now I can clearly iterate and see what was inside var a.
However, it was kind of annoying to alert once every value on the var a. What I wanna know if it's possible to display all the contents in just one pop of alert box?
Here is my code:
$.each(a, function(index, value) {
alert(index + ': ' + value);
});
The var a contains infos such as:
creationdate: date_here
id: SWFUpload
modificationdate: date_here
type: .jpg
index: 0
name: uploaded_filename.jpg
size: size_in_bytes
BTW: The var a is called via file upload script.
Why don't you just accumulate the values in an array, then display the whole array (for instance, using JSON)? Example:
var acc = []
$.each(a, function(index, value) {
acc.push(index + ': ' + value);
});
alert(JSON.stringify(acc));
In any case, I'd suggest using a debug tool like Firebug. So you could just use console.log(a) and be able to navigate freely through the objects's fields.
In firefox you could try:
alert(yourObject.toSource());
OR you could use some plugin:
See: jQuery Dump Plugin