How do I map a variable to object - javascript

I'm new to JSON and jQuery/JavaScript.
How would I pull in a object so that I can use it within jQuery, I've tried 2 attempts
var placements = document.querySelector(placements)
var message = document.querySelector(placements.message)
$.ajax({
type: 'GET',
url: 'https://raw.githubusercontent.com/kieranbs96/developer-exercise/master/data/recommendations.json',
async: false,
dataType: 'json',
success: function (data) {
$("header").append(placements.message);
}
});
Below is the JSON I'm trying to pull in:
{
"placements":[
{
"message":"If you like this, you might be into these",
"items":[
{
"id":"029148",
"name":"Woodblock Play Suit",
"price":"46.00"
},
{
"id":"0294526806",
"name":"Smock Dress",
"price":"39.00"
},
{
"id":"0297180006",
"name":"Cami",
"price":"9.00"
},
{
"id":"0298473606",
"name":"Asymmetric Wrap Cami Dress",
"price":"46.00"
},
{
"id":"0297155306",
"name":"Casual Stripe Tee",
"price":"16.00"
}
]
}
]
}
Marked as duplicate - the other question did not solve my problem - it has been solved by an answer to this question.

You haven't included what the error is or the expected output, but here's two potential errors.
You aren't utilizing the data object returned from your AJAX request.
The value associated with the placements key on your JSON object is an array of objects. Therefore, to access the message key, you'll need to traverse the array.
This is likely what your code should look like:
$("header").append(data.placements[0].message);

First off, you're missing the data object within your append function.
Second, you're missing the key notation of data.placements considering the fact that placements is an array.
You can either use data.placements[0].message to get your preferred data, or, if placements will be extended with more objects in the future, map through your objects like this:
data.placements.map(function(obj, index){
if(index == 0){
$("header").append(obj.message);
}
})
Not necessary if your array will always have a length of 1 of course

Related

How to pass the data as object in jquery ajax

I want to receive the value thought iterator, when I use
$('#someModal').find('input[name=nameProBangHHModal]').val(data[0].TenNhanQuyCach);
it works as expected.
But when I use an iterator, the return shows [object Object].TenNhanQuyCach - not the data returned.
I try to search for other topic but I'm stuck on this. How to get the data returned in array[data[0]] with the value from the iterator method?
Thank you for your time!
$.ajax({
url: 'someurl to retrive data',
type: 'POST',
data: {id:id},
success: function(data,status) {
var tenCot = ['nameProBangHHModal','valueBangHHModal',];
var tenCotTrongCsdl = ['TenNhanQuyCach','DonViTinh',];
console.log(tenCotTrongCsdl[0]);
for (i=0;i <= tenCot.length - 1;i++) {
$('#someModal').find('input[name="' + tenCot[i] + '"]').val(data[0]+'.'+tenCotTrongCsdl[i]');
}
oh i find out the answer after search topic for array: this one: How can I access and process nested objects, arrays or JSON?.
and find out that need to use [] for variable, not the ".".
this one work for me:
$('#someModal').find('input[name="' + tenCot[i] + '"]').val(data[0][tenCotTrongCsdl[i]]);

Parse JSON in Javascript from PHP

I am passing a json encoded string in an ajax response to my Javascript. When I console.log the json, after JSON.Parse, it looks like the following:
[
{"732":
{
"doctor_name":"First M. Last ",
"degree":"MD"
}
},
{"377":
{
"doctor_name":"First M. Last ",
"degree":"MD"
}
},
{"1092":
{
"doctor_name":"First M. Last",
"degree":"DO"
}
},
{"759":
{
"doctor_name":"First M. Last",
"degree":"MD"
}
},
{"1628":
{
"doctor_name":"First M. Last",
"degree":"DO"
}
}
]
I need to access each one of these objects without knowing the ids (in this case "732", "377", "1092", "759", etc.)
Not sure if my data is even structured properly but I cannot even use Object.keys(obj) as it returns an error of a non-object property.
The way I am structuring my PHP array is as follows:
foreach ($doctors as $group){
$doctor_results[][(int)$group->prac_id]=array(
'doctor_name' => (string)$group->name,
'degree' => (string)$group->degree,
);
} // end foreach
I want each array id to be used as the key, not sure if this makes much sense.
TYIA
You most likely want your PHP to look like:
foreach ($doctors as $group){
$doctor_results[(int)$group->prac_id]=array(
'doctor_name' => (string)$group->name,
'degree' => (string)$group->degree,
);
} // end foreach
Note the missing [], which would imply pushing an item onto a numeric array. The second set of brackets in your example is suggesting to PHP that the numeric element created should be an associative array with an item with the 'prac_id' as a key. PHP is automatically creating that associative array, creating the structure with your key nested one level further in than you want for being able to grab an item by 'prac_id' by simple key access in JavaScript. As is, you'd need a nested loop like in Darren's answer.
I heavily agree with the comments posted by Marty and Six Fingered Man, but if you wanted to loop through the json, this would work:
jQuery.each(obj, function(index, data){
jQuery.each(data, function(id, fields){
console.log(id); // returns the ID's of the objects: 732, 377,....etc
console.log(fields); // returns the fields for each object. (doctor_name & degree)
});
});
JSFiddle Demo
[
{prac_id:"732",data:
{
"doctor_name":"First M. Last ",
"degree":"MD"
}
},...]
foreach ($doctors as $group){
$doctor_results[][(int)$group->{'prac_id'}]=array(
'doctor_name' => (string)$group->{'data'}->{'name'},
'degree' => (string)$group->{'data'}->{'degree'},
);
} // end foreach
Your ajax response is array of OBJECT. If you encode it by json_encode($array), your ajax response is OK. You can check your ajax response here : http://json.parser.online.fr/
So I think you can modify your ajax call. You can just add this dataType: 'json' in your ajax. It will automatically handle your JSON response.
$.ajax({
url: 'your_ajax_url',
data: 'data',
dataType: 'json',
success: function(data)
{
$.each(data, function(index, obj){
$.each(obj, function(id, nested_obj){
console.log("ID: "+id);
console.log("doctor name: "+nested_obj['doctor_name']+",degree:"+ nested_obj['degree'] );
});
});
}
)}

Ajax multiple object return - Parsing

I am unable to parse the multiple object JSON on ajax success. But I can, when I receive a single object JSON.
Ajax call
$.ajax({
url: "ajax/filter.php",
dataType: "JSON",
type: "POST",
data: {
category: $categoryArr,
brand: $brandArr,
occasion: $occasionArr,
colour: $colourArr,
price_min: $price_min,
price_max: $price_max
},
success: function(data) {
data = JSON.parse(data);
$("#result").html(data["name"]);
}
});
PHP code for single object JSON
$products = R::findOne('products', $filterString, $filterArray); //returns single row from db
if (!empty($products)) {
echo $products;
} else {
echo "No Products are available for this search criteria";
}
Result: {"id":"1","name":"Malbari-Product1","brand_id":"1","category_id":"1","colour_id":"2","occasion_id":"2","price":"599","discount":"10","small_img":"images/products_small/1.png","big_img":"images/products_big/1.jpg","seller_id":"1"}
PHP code for multiple object JSON
$products = R::find('products', $filterString, $filterArray); //returns multiple rows from db
if (!empty($products)) {
echo $products;
} else {
echo "No Products are available for this search criteria";
}
Result: {"id":"1","name":"Malbari-Product1","brand_id":"1","category_id":"1","colour_id":"2","occasion_id":"2","price":"599","discount":"10","small_img":"images/products_small/1.png","big_img":"images/products_big/1.jpg","seller_id":"1"} {"id":"10","name":"Malbari-Product6","brand_id":"2","category_id":"1","colour_id":"1","occasion_id":"5","price":"350","discount":null,"small_img":"images/products_small/6.png","big_img":"images/products_big/6.jpg","seller_id":"2"}
I suppose, in case of multiple objects, i'm actually getting a single string instead of multiple object JSON.
Please help.
wouldn't you just want to return an array of JSON objects?
[ { "Name": "Object1" }, { "DifferentObject": "Object2" }]
Based on your comments, it seems that the problem is with the php find() and findOne() methods.
In order to use them both in the same way, it would be convenient to make sure both methods return a similar result like an array with either one or more objects in it. That way you can use them both the same way in your javascript.
What I would do, is create an empty array and add the results as objects in that array. You can return that array from your methods and where you now echo your results or error message out, you simply do an echo json_encode($function_result_or_error_message);. I would probably add an error key and message to the array before I do that to have the error message contained in the result.
For more details you would have to post your php find() and findOne() methods.

json result display first value

I have found several posts similar to this topic but nothing I have tried has actually worked. My question is simple and should be easy to answer. My return json object will have one key and one value. For my code below, the alert shows "[{"DISCOUNT":1}]" and all I am trying to do is parse out the "1" and display it. Ultimately, I want to plug that value into a variable and use for multiplication, but I can't even get the darn number to display by itself. My code is below:
function codeMatchTest() {
if ($('#dbReturnString').val() == '') {
alert("Please enter a discount code.");
} else {
$.ajax({
type: "POST",
url: "PROMO.svc/MatchCode",
contentType: "application/json",
dataType: "json",
data: JSON.stringify({ codeInput: $('#dbReturnString').val().toLowerCase() }),
success: function (json) {
alert(json.d);
/*alert (json.d.discount); // getting "undefined"
$.each(json.d, function (key, value) {
var discount = value;
});
alert("Success: " + discount); //getting "undefined" */
},
error: function () {
alert("There was an error with your request.");
}
});
}
}
I have found no good references on how to actually use the data in a json object. My json object will only consist of a single key and value and I will only ever need to use the value.
Also, I have tried several iteration using $.each and none work. Based on the jquery documentation, it should be very easy but I am having not luck.
If your alert is showing "[{"DISCOUNT":1}]" that means you have an object within an array.
try alert(json.d[0].DISCOUNT);
JSON parsed objects are case sensivetive, plus its seems that json.d contains a string (wich seems to be in json) rather than an object. Try:
var discount = JSON.parse(json.d);
discount = discount[0].DISCOUNT;
success: function(json) {
alert(json.d[0]["DISCOUNT"]);
}
First comment on your code, you are reinventing what jQuery does.
data: JSON.stringify({ codeInput: $('#dbReturnString').val().toLowerCase() }),
It should just be
data: { codeInput: $('#dbReturnString').val().toLowerCase() },
Now to get the data it is simple, you are returning an array with an object in it.
Let us look at it as a regular variable and not an Ajaqx call.
var json = [{"DISCOUNT":1}];
So you got an array? How do you get the object inside of it? You reference the index. Since you said there will only be one index being returned, than use [0] to access it.
success: function (json) {
alert(json[0].DISCOUNT);
To access the first item from the json you may use
alert(json.d[0].DISCOUNT);
Because json.d is an array and it contains one object which is 0 index. So, json.d[0] will select the first item/object from the array and using .DISCOUNT you can access the object's property. It's also possible to access the property like
alert(json.d[0]["DISCOUNT"]);
Try this way
You can use JSON.parse(json.d) / json.d
var data = json.d;
for(i=0;i<data.length;i++) {
alert(data[i].fieldname);
}

Deleting items from an array causes Uncaught TypeError

I have a few jQuery plugins that I made - all parse JSON feeds and render them using Mustache.js; each plugin takes an integer value of how many items to display.
I received a Uncaught TypeError: Cannot read property 'link' of undefined when trying to parse the Stack Overflow JSON feed with the following code:
$.ajax({
type: 'GET',
url: query,
contentType: "jsonp",
dataType: 'jsonp',
success: function (jsonp) {
/* loop through JSON items converting the time from UNIX timestamp
** format to readable words by parsing it through timeConverter() */
var i;
for (i = 0; i < jsonp.items.length; i++) {
if (i > num-1){
delete jsonp.items[i];
} else {
jsonp.items[i].creation_date = timeConverter(jsonp.items[i].creation_date);
}
}
var output = Mustache.render(must_template, jsonp);
element.html(output);
return element;
} //EOF CALLBACK
}); //EOF AJAX
As a quickfix I disabled the truncation by simply commenting out the delete operation. The error suggests that Mustache.js is trying to access part of the JSON object which no longer exists; yet the delete operation clearly only affects items which are above the user-defined limit.
When this behaviour occured there were still 20 items in the array.
Note:
Yes, I've answered this question myself; however - I'm more than willing to accept another answer if it shows best practice, a neater way or improves upon my answer in some way. :)
delete is a "lower-level" operator compared to arrays. It directly removes the object property, bypassing all the specific array logic and hence does not update the length of the array.
If you want to delete an element from an array, use either .splice [MDN], or in your case you can simply set the length of the array and iterate over the remaining elements afterwards:
jsonp.items.length = Math.min(num, jsonp.items.length);
for (i = 0; i < jsonp.items.length; i++) {
jsonp.items[i].creation_date = timeConverter(jsonp.items[i].creation_date);
}
Delete is not changing array count as you already found out, it's only removing key. To remove items from array you can use splice. Example:
var array2 = [ 1, 2, 3, 4 ];
array2.splice(2, 1);
console.log('---------------------------');
console.log(array2.length); // 3
console.log(array2[0]); // 1
console.log(array2[1]); // 2
console.log(array2[2]); // 4
console.log(array2[3]); // undefined
Working sample: http://jsfiddle.net/qbXjp/1/
After much googling I couldn't find anything, even StackOverflow had failed me. Then, by chance, I came across this unintended side-effect of my 'quick hack' of commenting out the delete line..
Due to the fact I hadn't commented out the whole if/else block, my timeConverter() function wasn't being ran on the items which would ordinarily be deleted. This confirmed that the combination of for() and if(){} / else{} were working correctly. So it appeared as though Mustache.js was trying to access items that were already deleted! Almost as if the length property of the items[] array wasn't being updated when items were being deleted.
I made a jsFiddle test case and this confirmed it was the issue. Here's the code and ouput:
$.ajax({
type: 'GET',
url: query,
contentType: "jsonp",
dataType: 'jsonp',
success: function (jsonp) {
/* loop through JSON items converting the time from UNIX timestamp
** format to readable words by parsing it through timeConverter() */
var i;
for (i = 0; i < jsonp.items.length; i++) {
if (i > num-1){
console.log("Deleting item. Current Count: "+jsonp.items.length);
delete jsonp.items[i];
console.log("Deleting item. New Count: "+jsonp.items.length);
} else {
jsonp.items[i].creation_date = timeConverter(jsonp.items[i].creation_date);
}
}
console.log(jsonp);
return element;
} //EOF CALLBACK
}); //EOF AJAX
I tried a quick fix of using a counter to count each deletion, and then subtracting the deletion counter from the length property (jsFiddle):
$.ajax({
type: 'GET',
url: query,
contentType: "jsonp",
dataType: 'jsonp',
success: function (jsonp) {
/* loop through JSON items converting the time from UNIX timestamp
** format to readable words by parsing it through timeConverter() */
var i, deleted = 0;
for (i = 0; i < jsonp.items.length; i++) {
if (i > num-1){
delete jsonp.items[i];
deleted++;
} else {
jsonp.items[i].creation_date = timeConverter(jsonp.items[i].creation_date);
}
}
jsonp.items.length -= deleted;
console.log(jsonp);
return element;
} //EOF CALLBACK
}); //EOF AJAX
Here was the output this generated:
This code then ran fine when placed back in to the test environment and utilised with Mustache.js. Using the delete keyword doesn't affect the length property when used on an array
Coming from a Java background I'd taken for granted the fact that length is a property, and not a function - and therefore it isn't nessacerily updated upon any changes being made to the array. A stupid mistake that cost me more time than it should've! However, I couldn't find any other posts regarding this so I thought I'd post it up in the hope it can help anyone else in a similar position!

Categories