select2: "text is undefined" when getting json using ajax - javascript

I'm having an issue when getting json results back to select2. My json does not return a result that has a "text" field so need to format the result so that select2 accepts "Name".
This code works if the text field in the json is set to "text" but in this case, I cannot change the formatting of the json result (code outside my control).
$("#e1").select2({
formatNoMatches: function(term) {return term +" does not match any items." },
ajax: { // instead of writing the function to execute the request we use Select2's convenient helper
url: "localhost:1111/Items.json",
dataType: 'jsonp',
cache: true,
quietMillis: 200,
data: function (term, page) {
return {
q: term, // search term
p: page,
s: 15
};
},
results: function (data, page) { // parse the results into the format expected by Select2.
var numPages = Math.ceil(data.total / 15);
return {results: data.Data, numPages: numPages};
}
}
});
I have looked into the documentation and found some statements you can put into the results such as
text: 'Name',
but I am still getting "text is undefined".
Thanks for any help.

note that select2 is always in {id,text} pair so you need to specify both
results: function (data, page) {
var newData = [];
_.each(data, function (item) {
newData.push({
id: item.Id //id part present in data
, text: item.DisplayString //string to be displayed
});
});
return { results: newData };
}
},

Thanks to #neel shah for solving my problem. i had just little problem, i didnt wanted to use extra library so thats why i changed to normal jquery.
so if wanna go for normal jquery or javascript.
results: function (data, page) {
var newData = [];
$.each(data, function (index,value) {
newData.push({
id: value.Id, //id part present in data
text: value.DisplayString //string to be displayed
});
});
}
OR
results: function (data, page) {
var newData = [];
for ( var i = 0; i < data.length; i++ ) {
newData.push({
id: data[i].Id, //id part present in data
text: data[i].DisplayString //string to be displayed
});
}
All credits go to neel shah. Thanks again.

Related

Add Categories to Highcharts via Loop

I'm trying to add a list of categories as the xAxis for my bar chart using JavaScript and a JSON object. I've thus far had no success as the following code produces the following along the xAxis:
[object Object]
1
2
The JSON object I'm receiving is like this:
0: {Item: "textforyou", Num: 88}
1: {Item: "MoreText", Num: 22}
2: {Item: "SimpleStuff", Num: 85}
I'd like the have the categories on the xAxis look more like this:
textforyou
MoreText
SimpleStuff
This bit of code is where I'm taking my JSON object and trying to get the categories and series data for it.
$.ajax({
xhrFields: { withCredentials: true },
url: areaUrl + "api/Problem/ProblemsYTD",
success: data => {
self.isLoading(false);
self.data(data);
self.setPlotData(data);
self.isLoaded(true);
},
error: data => {
self.loadingError(true);
}
});
}
self.setPlotData = (data: any) => {
var len = data.List.length,
i;
var dataCats = new Array();
for (i = 0; i < len; i++) {
dataCats.push(
{ name: data.List[i].Service }
)
}
self.plotDataLabels.push({ data: dataCats });
var dataItems = [];
for (i = 0; i < len; i++) {
dataItems.push(
{ y: data.List[i].DaysOpen }
)
}
self.plotData.push({ data: dataItems });
}
Lastly, on the page where the bar chart is being created, this is the command I have for the xAxis category section of the page.
xAxis: {
categories: viewModel.plotDataLabels(),
crosshair: false
},
I'm able to do this fine for the series data, but I can't seem to get it right for the categories/text. Any help would be appreciated.
EDIT: Per Request, when I console.log ViewModel.plotDataLabels(), I get a single object back with "data: Array[3]". Once I access that array, everything appears as the following
Dropdown 0: Object
Dropdown 1: Object
Dropdown 2: Object
name: "SimpleStuff"
__proto__: Object
You need to manipulate your ViewModel.plotDatalabels() to ensure you get just the name and not the whole object. This should work, replace your categories value with the following
categories: viewModel.plotDataLabels().map(function(obj){ return obj.name; })

Find if item in collection with value exists

First of all, here is my very simple component :
var RenewedLoanModal = new Vue ({
el: '#myModal',
data:
{
responses: []
}
});
responses is filled up by an ajax call, it is an array of objects.
Here is the structure :
responses: [
{error: 'foo', message: 'foo', id: 'foo', success: true},
{error: 'bar', message: 'bar', id: 'bar', success: false},
...
]
I am trying to know if one of these object have a success: false but I didn't find anyway to check it.
Is there a way to iterate through the responses collection in a method, not in the view rendering ? Or maybe a v-if test ?
There are many ways to check if an item exists in a collection by its properties.
Plain Javascript
The first thing you could do using only plain javascript is the following:
var success = false
for (var i = 0; i < responses.lenth; i++) {
if (responses[i].success === true) success = true
}
ECMAScript 6
You can do it in ES6 like this:
var success = responses.reduce((prev, cur) => prev || cur.success, false)
Functional programming
Another more declarative way is by using the Ramda.js library:
// if 'any' of the elements satisfy the predicate
var success = R.any(response => response.success === true)(responses)
// or more briefly
var success = R.any(response => response.success)(responses)
Hooking it up in Vue.js
After you create say, a computed property with the above return result, you can hook it up to a v-if or a v-show if you want to conditionally display something.
If possible, I would use:
data: {
hadError: false,
responses: []
}
and let the addResponse(data, resp) do the job:
if(resp.success === false) data.hadError = true;
data.responses.push(resp);
otherwise:
for(i=0; i<responses.length; i++) {
if(response[i].success === false)
.....
}

Manipulate ajax response

I have a ajax post method. I get an object from the backend
$.ajax({
type: "POST",
url: URL_one,
data: submitData
}).then(function (response) {
console.log("Ajax response", response);
});
and when i do a console.log(response); inside the post method, i see the following data.
>Object{Info:Array[200]}
>Info:Array[200]
>[0-99]
>0:Object
name:'Ashley'
on_pay: true
valid:"0"
>[100-199]
So each array has objects like one mentioned above with name, on_pay and valid. I want to do the following
Since all on_pay values are true in my case, i need to convert it to false. Also valid has string of 0. I need to put all values as blank instead of 0.
Is it possible to do ?? Can someone please shed some light on these.
Considering the JSON structure that you show, following should work to change the on_pay value:
response.Info.forEach(function(item){
item.on_pay = false;
});
If I'm understanding your question correctly, response is an array of items. You want to keep those items intact, but turn the on_pay property false and valid to an empty string.
You can use Array::map() to transform each item.
/*jslint node:true*/
"use strict";
// I am assuming your response looks something like this
var response = {
Info: [
{
name: "Ashley",
on_pay: true,
valid: "0"
},
{
name: "Jim",
on_pay: true,
valid: "0"
},
{
name: "John",
on_pay: true,
valid: "0"
}
]
};
// This will produce a new variable that will hold the transformed Info array
var fixedResponseInfo = response.Info.map(function (item) {
item.on_pay = false;
item.valid = "";
return item;
});
// This will edit the response.Info array in place
response.Info.forEach(function (item) {
item.on_pay = false;
item.valid = "";
});
console.log(fixedResponseInfo);
console.log(response);
This will keep your original response variable and produce a new variable fixedResponseInfo that contains the transformed array. If you don't care whether data in response is changed, you can use Array::forEach() to iterate instead.

Unable to hold onto variable after fetching JSON data

I am using the highstocks charting library and JQuery for this question. I am attempting to create one chart that is partitioned into three pieces, each with a different set of data. To read in the data, I am using an example from the highstock site, with the following code:
var seriesOptions = [],
names = ['MSFT', 'AAPL', 'GOOG'];
$.each(names, function(i, name) {
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=' + name.toLowerCase() + '-c.json&callback=?', function(data) {
seriesOptions[i] = {
name: name,
data: data
};
});
});
After this code is processed, I use the seriesOptions variable as the series value for each of the three charts as such:
$('#container').highcharts('StockChart', {
// misc options
series: [
seriesOptions[0],
seriesOptions[1],
seriesOptions[2],
]
}
However, it seems that the seriesOptions variable is null after it comes out of the $.getJSON() method call. How can I get around this, and what is happening to the seriesOptions variable after the $.getJSON() call?
Thanks
EDIT: Specific error:
Uncaught TypeError: Cannot read property 'type' of undefined. I am pretty sure that this is referring to the seriesOptions variable, but I'll include it for clarity.
You're probably executing the highCharts call before the AJAX call has completed. You're also doing an AJAX call in a loop (albeit a small loop, it can still have the same general issues) - if you can - try and make this 1 AJAX call with all the params. If that's not an option - you can loop, and verify all the calls are done, then process:
var seriesOptions = [],
names = ['MSFT', 'AAPL', 'GOOG'];
var completedCalls = 0;
for (var i = 0; i < names.length; i++) {
var name = names[i];
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=' + name.toLowerCase() + '-c.json&callback=?', function(data) {
seriesOptions.push({
name: name,
data: data
});
completedCalls++;
if (completedCalls == names.length) {
//All ajax calls done, do highcharts magic!
$('#container').highcharts('StockChart', {
// misc options
series: [
seriesOptions[0],
seriesOptions[1],
seriesOptions[2],
]
})
}
});
}
jQuery provides an interface using $.when for resolving multiple ajax calls using deferred/promise objects. An example using your configuration can be seen below.
var seriesOptions = [];
$.when(
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=msft-c.json&callback=?'),
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=aapl-c.json&callback=?'),
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=goog-c.json&callback=?')
).done(function (r1, r2, r3) {
seriesOptions.push({
name: "MSFT",
data: r1
});
seriesOptions.push({
name: "AAPL",
data: r2
});
seriesOptions.push({
name: "GOOG",
data: r3
});
$('#container').highcharts('StockChart', {
// misc options
series: [
seriesOptions[0],
seriesOptions[1],
seriesOptions[2],
]
});
});

Accessing JSON objects from objects without titles in JQuery

I am receiving this JSON file back from an AJAX call:
[
{
"LINKNAME": "Annual Training",
"HITS": 1
},
{
"LINKNAME": "In Focus Newsletter",
"HITS": 1
},
{
"LINKNAME": "NITA (secured)",
"HITS": 1
},
{
"LINKNAME": "Your Current Events",
"HITS": 1
},
]
Here is my AJAX call:
$(document).ready(function(e) {
$.ajax({
method: "GET",
url: url,
}).done(function(api) {
console.log(api);
var obj = JSON.parse(api),
totRes = Object.keys(obj).length;
$.each(obj.children, function (index, value) {
alert(value);
});
}).fail(function( jqXHR, textStatus ) {
alert('Service Catalog: Error loading '+jqXHR+' data. Request fail caused by: '+textStatus);
});
});
I need to be able to extract the data from the JSON and use it but since the JSON objects aren't gioven a title then I am unsure how to extarpolate the data inside the inner object. Thanks in advance. Please ask if you do not understand my question.
Your JSON is just an array of plain objects.
To iterate over an array, you can use various methods. Since you're using jQuery, I'll just suggest $.each:
var arr = JSON.parse(api);
$.each(arr, function(i, obj) {
// access whatever property you want... obj[LINKNAME] or whatever
});
You can also use Array.prototype.forEach, or even just your basic for loop:
arr.forEach(function(obj) {
// obj is the current plain object... e.g. { LINKNAME: 'whatever', HITS: 0 }
});
I would also consider paying attention to how you are referring to the objects that you are receiving. While it is true that arrays are objects, and plain objects are objects, I would probably stick to referring to an array as an array, and a plain object as an object. This is because what you are receiving, in the form of JSON, is an array object of plain objects (or more simply, an array of objects).
Calling the array an "object" and referring to it as obj may confuse you when reading through the code quickly (yes, it is a good abstraction for potential extensibility if you end up not always receiving an array, but that's not the case here.)
Also, to once you have access the object in the each loop, you can iterate over the properties of the object if you need to (taken from this answer):
var obj = {
"a": 1,
"b": 2,
"c": 3
};
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
// or if (Object.prototype.hasOwnProperty.call(obj,prop)) for safety...
alert("prop: " + prop + " value: " + obj[prop])
}
}
First, you can add the setting dataType: 'json' when you send a request. This way you'll have api as javascript array.
Then you'll be able to iterate it via javascript for.
$.ajax({
method: "GET",
url: url,
dataType: "json"
}).done(function(api) {
for (var i = 0; i < api.length; i++) {
var name = api[i]["LINKNAME"],
hits = api[i]["HITS"];
// ...
}
// ...
$(document).ready(function(e) {
$.ajax({
method: "GET",
url: url,
}).done(function(api) {
if (api && api.length > 0) {
api.forEach(function (item) {
console.log(item); // logs whole object
console.log('item name %s', item.LINKNAME);
console.log('item hits %s', item.HITS);
});
}
}).fail(function( jqXHR, textStatus ) {
alert('Service Catalog: Error loading '+jqXHR+' data. Request fail caused by: '+textStatus);
});
});
You can filter the results to make sure you're only using objects that contain both 'LINKNAME' and 'HITS' pretty easily:
.done(function(api) {
if (api && api.length > 0) {
var objs = api.filter(function (item) {
return item.hasOwnProperty('LINKNAME') && item.hasOwnProperty('HITS');
});
objs.forEach(function (item) {
console.log(item); // logs whole object
console.log('item name %s', item.LINKNAME);
console.log('item hits %s', item.HITS);
});
}
});

Categories

Resources