Get values from JSON data [object] - javascript

debugging screenshot
$.ajax({
url: postUrl,
type: 'GET',
dataType: 'json',
data: { "id": num },
contentType: "application/json; charset=utf-8",
success: function (data) {
$.each(data, function (id, allFollowers) {
result += 'Title : ' + **data** + '<br/>';
});
I've tried: data.allFollowers[0].screeName, data[0].allFollowers[0].screeName...
I can see these values exist here in debug mode, however it returns a null error..?

Based on your screenshot, I'm assuming the data somewhat looks like this:
//data is an object, with an array of allFollowers objects
var data = {
"allFollowers": [{
"AlternateText": "no photo",
"profileImage": "http://foo.com/foo",
"screenName": "foo",
"userID": 15785100
},
{
"AlternateText": "no photo",
"profileImage": "http://bar.com/bar",
"screenName": "bar",
"userID": 12345678
}
]
};
You're iterating on data only/instead of its child array (allFollowers). So you'll have to go one level deeper:
$.each(data, function(key, obj) {
$.each(obj, function(i, value){
console.log("screen name %i: %o, User ID: %o", i, value.screenName, value.userID);
})
})
Console:
screen name 0: "foo", User ID: 15785100
screen name 1: "bar", User ID: 12345678
Hth...

I think your mistake is about using $.each function. You should refer to your data using some code like:
$.each(data, function (id, follower) {
result += 'Title : ' + follower + '<br/>';
});
For more info refer to this jQuery API Documentation.

Related

How to import JSON object with arrays into ajax autocomplete response?

A company email-generating application I'm working on has an autocomplete input to autofill email theme data into a form. The data is returned as a JSON object, but a couple of the object values extraps and extraul contain multidimensional arrays. I'm able to get the plain key:value data just fine out in the response, but I can't seem to figure out how to pull the arrays in so I can loop over them to update certain sections of the form.
Here's a look at some of the JSON code coming in:
0:
emaildate: "2019-01-10"
extraps: Array(2)
0: {extrap: "test paragraph", position: 1}
1: {extrap: "another paragraph", position: 3}
length: 2
__proto__: Array(0)
extraul: Array(4)
0: {ulid: 1, position: 2, li: "list item 1", liposition: 1}
1: {ulid: 1, position: 2, li: "list item 2", liposition: 2}
2: {ulid: 1, position: 2, li: "list item something new", liposition: 3}
3: {ulid: 1, position: 2, li: "A new list item", liposition: 4}
length: 4
__proto__: Array(0)
id: 44
label: "Some Kind of Email Theme - 2019-01-10"
lastupdated: "2019-01-06 02:00:04"
store: "Premier"
themedesc: "Here's a description of the theme."
themeimage: null
themeincludeextrap: 1
themeincludeul: 1
themelink: "some-kind-of-email-theme"
themelinkinclude: 1
themename: "Some Kind of Email Theme"
themenotes: "Some notes about it"
themesortorder: 0
value: "Some Kind of Email Theme"
__proto__: Object
length: 1
__proto__: Array(0)
And here's a look at the javascript to bring it in from autotheme.php:
//Autofill Theme Info based on text entry
$( "#themename" ).autocomplete({
source: function( request, response ) {
$.ajax({
url: "autotheme.php",
type: "GET",
dataType: "json",
data: {
q: request.term
},
success: function(data) {
console.log(data);
response($.map(data, function(item) {
return {
id: item.id,
value: item.value,
label: item.label,
themename: item.themename,
themenotes: item.themenotes,
themedesc: item.themedesc,
themeimage: item.themeimage,
themeincludeextrap: item.themeincludeextrap,
themeincludeul: item.themeincludeul,
themelinkinclude: item.themelinkinclude,
themelink: item.themelink,
themeextraps: item.extraps,
themeextraul: item.extraul
}
}))
},
error: function(errorThrown){
console.log(errorThrown);
console.log("There is an error with theme autocomplete.");
}
});
},
minLength: 2,
select: function(event, ui) {
if (ui.item) {
$this = $(this);
$('#themeid').val('');
$('#extratext').html('');
$('#themename').val(ui.item.themename);
$('#themenotes').val(ui.item.themenotes);
$('#themedesc').val(ui.item.themedesc);
var themeimage = ui.item.themeimage;
var themeincludeextrap = ui.item.themeincludeextrap;
var themeincludeul = ui.item.themeincludeul;
var themelinkinclude = ui.item.themelinkinclude;
var themeextraps = ui.item.extraps;
var themeextraul = ui.item.extraul;
if(themeextraps !== undefined) {
var extrapcount = themeextraps.length;
}
if(themeextraul !== undefined) {
var extraulcount = themeextraul.length;
}
if((themeextraps !== undefined) || (themeextraul !== undefined)) {
var extratextpositions = {};
$.each(themeextraps, function(i, themeextraps) {
extratextpositions[themeextraps.position] = 'p';
})
$.each(themeextraul, function(i, themeextraul) {
extratextpositions[themeextraul.position] = 'ul';
})
$.each(extratextpositions, function(key, value) {
if(extratextpositions[key] == 'p') {
addExtraP.call(this);
} else {
addExtraUl.call(this);
}
});
$('#themelink').val(ui.item.themelink);
if(themelinkinclude == 1) {
$('#themelinkinclude').prop("checked", true);
} else {
$('#themelinkinclude').prop("checked", false);
}
event.preventDefault();
}
},
open: function(event, ui) {
$(".ui-autocomplete").css("z-index", 1000);
},
complete: function(){
$("#themename").removeClass("ui-autocomplete-loading");
}
}
});
I'm able to get the simple key:value values just fine, but I get undefined for the arrays. I'm sure there's a different way I need to pull those in, but I don't know how and can't seem to find the answer in other threads on here. Any help would be greatly appreciated!
Figured out a way to get around this problem, thanks to some help from #Bibberty. I'm not sure if this is the most graceful or easy way to solve it, but it worked for me. I created an array from the JSON data values, then created variables from the arrays within the data array and added them to the response return value. Here's the new functional code (or, at least, the part that matters):
//Autofill Theme Info based on text entry
$( "#themename" ).autocomplete({
source: function( request, response ) {
$.ajax({
url: "autotheme.php",
type: "GET",
dataType: "json",
data: {
q: request.term
},
success: function(data) {
const results = data.map(function (value, label) {
return [value];
})
var extraps = results[0][0]['extraps'];
var extraul = results[0][0]['extraul'];
response($.map(data, function(item) {
return {
id: item.id,
value: item.value,
label: item.label,
themename: item.themename,
themenotes: item.themenotes,
themedesc: item.themedesc,
themeimage: item.themeimage,
themeincludeextrap: item.themeincludeextrap,
themeincludeul: item.themeincludeul,
themelinkinclude: item.themelinkinclude,
themelink: item.themelink,
extraps: extraps,
extraul: extraul
}
}))
$("#themename").removeClass("ui-autocomplete-loading");
},
error: function(errorThrown){
console.log(errorThrown);
console.log("There is an error with theme autocomplete.");
}
});
},
minLength: 2,
select: function(event, ui) {
if (ui.item) {
$this = $(this);
console.log(ui.item.extraps);
$('#themeid').val('');
$('#extratext').html('');
$('#themename').val(ui.item.themename);
$('#themenotes').val(ui.item.themenotes);
$('#themedesc').val(ui.item.themedesc);
var themeimage = ui.item.themeimage;
var themeincludeextrap = ui.item.themeincludeextrap;
var themeincludeul = ui.item.themeincludeul;
var themelinkinclude = ui.item.themelinkinclude;
var themeextraps = ui.item.extraps;
var themeextraul = ui.item.extraul;
if(themeextraps !== undefined) {
var extrapcount = themeextraps.length;
}
if(themeextraul !== undefined) {
var extraulcount = themeextraul.length;
}
...

Select2 won't load remote json response

I have an API that is called by Select2 (v4.0.5) however the debug message in the console says:
Select2: The AJAX results did not return an array in the results key of the response.
When I review the documentation at Select2's documentation site I seem to be following it correctly. This is the javascript I use on the webpage:
$('#account_id').select2({
debug: true,
minimumInputLength: 3,
dataType: 'json',
ajax: {
url: '/api/account-query',
data: function (params) {
var query = {
search: params.term,
v: "new"
}
return query;
},
}
});
This is the response from the API (sensitive bits redacted):
{
"results": [{
"id": "redacted-1",
"text": "text redacted 1"
},{
"id": "redacted-2",
"text": "text redacted 2"
},{
"id": "redacted-3",
"text": "text redacted 3"
},{
"id": "redacted-4",
"text": "text redacted 4"
},{
"id": "redacted-5",
"text": "text redacted 5"
}]
}
If I take the select2 code and supply it with the static json response (without results prepended, just the array) it works just fine.
What am I missing?
Thanks!
You have to provide the processResults callback function so Select2 able to render result in proper way.
I have created a jsfiddle (https://jsfiddle.net/shcavbng/) demo that doing the same.
$('#account_id').select2({
debug: true,
minimumInputLength: 3,
dataType: 'json',
ajax: {
url: 'https://reqres.in/api/users',
data: function (params) {
console.log('params =>' , params);
var query = {
search: params.term,
v: "new"
}
return query;
},
processResults: function (data) {
console.log('results =>' , data);
data = data.data.reduce(function(o,i){o.push({id:i.id,text:i.first_name});return o;},[]);
console.log('results =>' , data);
return {
results: data
};
}
}
});
I figured it out, and as expected I was overlooking a simple aspect:
Content-Type header needed to be application/json vs text/html

Construct JSON in proper format with Jquery

I am trying to reformat a dynamically created JSON output into a format that can be consumed by the x-editable select type source[]. I need help building the array so that the re-formated JSON output looks like this:
{value: 2, name: 'Maintenance'},
Below is a sample original JSON which I am consuming:
{"COLUMNS":["SECTIONCOMMONNAME"],"DATA":[["Aircraft Overview"],["Email Server Settings"],["Maintenance"],["Page Sections"],["WOW"]]}
The code I am using is:
$(document).ready(function () {
var myURL = 'https://api.myjson.com/bins/3nzdj';
var myarray = [];
$.ajax({
url: myURL,
dataType: 'json',
success: function (e) {
console.log('My created console output:' +'<br>');
$.each(e.DATA, function (i, jsonDataElem) {
console.log("{value: " + i + ', ' + "name: " + '"'+this+"'}");
var item = {
"value": i,
"name": this
};
myarray.push(item);
});
var newJson = JSON.stringify(myarray);
console.log('My stringify output:' +'<br>' +newJson);
}
});
$('.sectionsAvailable').editable({
name: 'template',
type: 'select',
placement: 'right',
send: 'always',
value: 1,
source: [], //newJson (my new var)
/* should be in this format:
source: [{
value: 1,
text: 'text1'
}, {
value: 2,
text: 'text2'
}]*/
});
};
});
After the stringify, the output is close, but wont work. It looks like this:
{"value":2,"name":["Maintenance"]}
and needs to look like thisL
{value:2,name:'Maintenance'},
Here is a JSfiddle showing the output here.
it seems you are assigning complete array instead of value at index 0 try this
var item = {
"value": i,
"name": this[0] // gives elemnt at index 0
};
myarray.push(item);
FIDDLE
I was able to answer my own question. There might be a better way, but this works:
var myURL = 'https://api.myjson.com/bins/3nzdj';
$.getJSON(myURL, function(data) {
var output = '';
$.each(data.DATA, function(key, val) {
output +='{value: ';
output += "'"+key+"'";
output +=',text:';
output += "'"+val+"'";
output +='}';
output +=',';
});
var outputAdapted = '['+output+']'
$('.sectionsAvailable').editable({
name: 'template',
type: 'select',
placement: 'right',
send: 'always',
value: 1,
// should be in this format:
source:
function() {
return outputAdapted;
},
});
});
My FIDDLE I hope this can help someone else.

parse a result from AJAX request

I have this ajax request:
var rootURL = "http://localhost/myapp/api/api.php";
$.ajax({
type: 'GET',
url: rootURL + '/favourites',
dataType: "json",
success: function(list) {
},
error: function(list) {
}
});
and the api.php makes a query to DB and the encoded result
echo '{"result": ' . json_encode($result) . '}';
is like this:
{
"result": [
{
"ID": "1",
"username": "username1",
"name": "name1",
"year": "year1"
},
{
"ID": "2",
"username": "username2",
"name": "name2",
"year": "year2"
}
]
}
Now how can I get and print the two rows of the JSON result list in success callback in Javascript?
I tried this:
var decoded = JSON.parse( lista );
but I receive an error: JSON.parse: unexpected character at line 1 column 1 of the JSON data
Thanks
You dont't need to parse, just you need to iterate the array inside the result.
do like this:
success: function(list) {
$.each(list.result,function(index,item){
console.log(item);
});
}
FIDDLE DEMO
Don't call JSON.parse. jQuery does that for you when you say dataType: "json". list is an object. So just access list.result, which contains the result array.
Also, your PHP shouldn't build the JSON by hand like that. It should do:
echo json_encode(array('result' => $result));

Bootstrap Typeahead with AJAX source: not returning array as expected

I am having a lot of trouble getting bootstraps typeahead to work properly with an AJAX source.
If I alert out the array that is being returned it is perfectly fine, even when I hard code it to test it. It seems to return nothing most of the time or only a few items from the array when you have typed in a near match.
Here is what I have at the moment:
$('#companyNameInput').typeahead({
source: function(query, process){
$.ajax({
url: ROOT+'Record/checkCompanyName',
async: false,
data: 'q='+query,
type: 'POST',
cache: false,
success: function(data)
{
companiesFinal = [];
map = {};
companies = $.parseJSON(data);
$.each(companies, function(i, v){
map[v.name] = v.id;
companiesFinal.push(v.name);
})
}
})
process(companiesFinal);
// return ['test1', 'test2'] This works fine
return companiesFinal;
}
Does anyone have an idea why this is working properly?
Here is an example of the object array returned from my PHP script. Objects with IDs 1 and 1216 show up on the typeahead dropdown, but non of the others do. I can not see any patterns or clue as to why only these would show and not the others.
[
   {
      "id": "1265",
      "score": "40",
      "name": "LMV AB"
   },
   {
      "id": "10834",
      "score": "33",
      "name": "Letona"
   },
   {
      "id": "19401",
      "score": "33",
      "name": "Lewmar"
   },
   {
      "id": "7158",
      "score": "33",
      "name": "Lazersan"
   },
   {
      "id": "3364",
      "score": "33",
      "name": "Linpac"
   },
   {
      "id": "1216",
      "score": "33",
      "name": "L H Evans Limted"
   },
   {
      "id": "1",
      "score": "33",
      "name": "LH Evans Ltd"
   },
   {
      "id": "7157",
      "score": "33",
      "name": "Lazersan"
   }
]
And finally the array that is past in process(companiesFinal):
["LMV AB", "Letona", "Lewmar", "Lazersan", "Linpac", "L H Evans Limted", "LH Evans Ltd", "Lazersan"]
Anyone have any clue? I am still totally clueless as to why this isn't working still :(
$('#companyNameInput').typeahead({
source: function(query, process){
companyTOut = setTimeout(function(){
return $.ajax({
url: ROOT+'Record/checkCompanyName',
data: 'q='+query,
type: 'POST',
dataType: 'json',
cache: false,
success: function(data)
{
var count = 0;
var companiesFinal = [];
map = [];
$.each(data, function(i, v){
map[v.name] = [v.id, v.score];
companiesFinal.push(v.name);
})
process(companiesFinal);
}
})
}, 250)
},
minLength: 2,
highlighter: function(item)
{
$('#companyNameInput').closest('.control-group').removeClass('success')
companyLocked = false;
return '<span class="unselectable" title="'+map[item].score+'">'+item+'</span>';
},
updater: function(item)
{
selectedEntityId = map[item][0];
selectedCountryScore = map[item][1];
lockCompany(selectedEntityId);
return item;
}
});
$output .= '['.$output;
foreach($results as $result) {
$output .= '{"id":"'.$result['id'].'",';
$output .= '"score":"'.$result['score'].'",';
$output .= '"name":'.json_encode($result['name']).'},';
}
header('Content-Type: application/json');
echo substr($output, 0, strlen($output)-1).']';
Console output for "parm":
[Object, Object, Object, Object, Object, Object]
0: Object
id: "25024"
name: "part"
score: "75"
__proto__: Object
1: Object
id: "15693"
name: "pari"
score: "75"
__proto__: Object
2: Object
id: "28079"
name: "Pato"
score: "50"
__proto__: Object
3: Object
id: "18001"
name: "PASS"
score: "50"
__proto__: Object
4: Object
id: "15095"
name: "PSR"
score: "33"
__proto__: Object
5: Object
id: "22662"
name: "PRP"
score: "33"
__proto__: Object
length: 6
__proto__: Array[0]
Update 2
Ah, your service returns items that actually don't match the query parm. Your typeahead query is 'parm', with which none of the returned results match. You can override the matcher function used by the typeahead plugin, see the docs. Simply implement it as return true to match all results returned by your service.
Update 1
This is an updated version, that maps the name to an id, which can be used later. A jsfiddle is available.
var nameIdMap = {};
$('#lookup').typeahead({
source: function (query, process) {
return $.ajax({
dataType: "json",
url: lookupUrl,
data: getAjaxRequestData(),
type: 'POST',
success: function (json) {
process(getOptionsFromJson(json));
}
});
},
minLength: 1,
updater: function (item) {
console.log('selected id'+nameIdMap[item]);
return item;
}
});
function getOptionsFromJson(json) {
$.each(json, function (i, v) {
nameIdMap[v.name] = v.id;
});
return $.map(json, function (n, i) {
return n.name;
});
}
Original answer
You need to make the call async and call the process callback from within the success callback like this:
$('#companyNameInput').typeahead({
source: function (query, process) {
$.ajax({
url: ROOT + 'Record/checkCompanyName',
// async: false, // better go async
data: 'q=' + query,
type: 'POST',
cache: false,
success: function (data) {
var companiesFinal = ... // snip
process(companiesFinal);
}
})
}
});
The return ['test1', 'test2']; works, because the source function is then basically set to:
// do ajax stuff, but do nothing with the result
// return the typeahead array, which the typeahead will accept as the result:
return ['test1', 'test2'];
Notes
There is a one-liner to fill companiesData:
var companiesFinal = return $.map(data, function (n, i) { n.name; });
And you probably want to declare your variables using var; otherwise they'll have global scope, which will bite you.

Categories