Format JSON from controller for use by a plugin - javascript

I'm getting a JSON string from my controller:
public ActionResult Highlight()
{
var statesHighlight =
db.Jobs
.Select(r => r.Location);
return Json(statesHighlight , JsonRequestBehavior.AllowGet);
}
I'm getting it via an Ajax request like so:
$.ajax({
async: false,
url: '#Url.Action("Highlight", "Jobs1")',
data: JSON.stringify(),
type: 'POST',
success: function (data) {
citydata = data;
}
});
The issue is that this doesn't maintain the format of my string. Calling the controller action shows that it's correctly formatted JSON, but once it comes out of my Ajax request, it's not. Here it is directly from the controller:
["HDQ","HDQ","EVA","HDQ","HDQ","HDQ","EVA","SVF","SVF","SVF","SVF","DFC","DCF","Feedlot","DCF","DCF","DCC","AGNW","AGNW"]
Is there any way that I can ensure that this is the value set to the variable before I pass it along to my plugin?
The plugin I'm using is called ImageMapster. Currently, I have the JSON hard coded for it and it works as intended.
var data = $.parseJSON($('#map-data').text());
var cities = $.parseJSON($('#city-data').text());
$('img').mapster({
mapKey: 'state',
clickNavigate: true,
isSelectable: false,
highlight: false,
onConfigured: function () {
// make the array into a comma-sparated list
var state_list = data.join(',');
var city_list = cities.join(',');
// the 'set' activates the areas
$('img').mapster('set', true, state_list, options = { fillColor: '638EA5' });
$('img').mapster('set', true, city_list, options = { fillColor: 'ffffff' });
}
});

Is your statesHighlight just a simple System.String[] ? then you will get always the plain string array object in your javascript.
But you want something like var a = { data1 : "a", data2 : "b", data3 : "c" };
JSON basically consists of Key & Value. The equivalent of the data type in C# would be Dictionary. You need to pass Dictionary type or any other key&value object when you parse your data to Json.
public ActionResult Highlight()
{
var statesHighlight =
db.Jobs
.Select(r => r.Location);
// statesHighlight should be Dictionary
// if you want a JSON result having keys and values.
return Json(statesHighlight , JsonRequestBehavior.AllowGet);
}
In case you need just a keyname for the string array, you can set up a keyname like this.
//return Json(statesHighlight , JsonRequestBehavior.AllowGet);
return Json(
new {
keyname = statesHighlight
}
, JsonRequestBehavior.AllowGet
);

I was looking the wrong place entirely for an answer. The formatting was just fine; I discovered this when I took a closer look at the formatting of the variables I was originally using. As it turns out, I was making things more complicated than they needed to be. Bypassing one of my incremental steps ended up being the right solution. Here is my final code:
//retrieve JSON strings from controller
var citydata = {};
$.ajax({
async: false,
url: '#Url.Action("Highlight", "Jobs1")',
method: 'GET',
success: function (data) {
citydata = data;
}
});
var statedata = {};
$.ajax({
async: false,
url: '#Url.Action("HighlightState", "Jobs1")',
method: 'GET',
success: function (data) {
statedata = data;
}
});
//imagemapster to generate map behaviors
$('img').mapster({
mapKey: 'state',
clickNavigate: true,
isSelectable: false,
highlight: false,
onConfigured: function () {
// make the array into a comma-sparated list
var state_list = statedata.join(',');
var city_list = citydata.join(',');
// the 'set' activates the areas
$('img').mapster('set', true, state_list, options = { fillColor: '638EA5' });
$('img').mapster('set', true, city_list, options = { fillColor: 'ffffff' });
}
});

Related

POST with Ext.Ajax.request?

I am new to ExtJS and I am trying to implement a combo box and 'Save' button that will save the "boxStatus" for all of the records selected in my grid (there is a little checkbox column for selecting records, and a combo box for the status). I have tried with the following ajax call:
saveBulkBoxComments : function(){
var formObj = this.getPositionPanel().getForm();
var fieldValues = formObj.getFieldValues();
Ext.Ajax.request({
url: SAVE_BULK_BOX_COMMENTS_URL,
method: 'POST',
params: {
positionDate: this.parentRecordData.data.positionDate,
groupIds: this.parentRecordData.data.groupId,
boxStatus: fieldValues.boxStatus,
csrComment: fieldValues.csrComment
},
success : function(response) {
//how do I update box status for all records selected?
this.loadPositions();
},
scope: this
});
}
Here is the Java:
return getReturnValue(new Runnable() {
public void run() {
String groupIdList[] = groupIds.split(",");
String user = mercuryUserScreenNameGetter.getValue(request);
Date date = Utils.parseDate(positionDate, DATE_FORMAT);
Stream.of(groupIdList)
.forEach(groupId ->
positionsDataMediator.addBoxAnnotation(date,user, groupId, csrComment, boxStatus));
}
});
I am not really sure how to post all of the boxStatus for all of the records selected. Would I have to write a method that iterates over all of the records when I hit Save? That seems wrong...Thanks for the help.
After some fiddling, I got it working. The trick was to iterate over each groupID, for all of the selected records...this way I was able to update the boxStatus for each of those records at once:
saveBulkBoxComments : function(){
grid = this.getPositionPanel();
var store = grid.getStore();
formObj = this.getBoxCommentsFormPanel().getForm();
var fieldValues = formObj.getFieldValues();
var value='';
selectedRecords = grid.getSelectionModel().getSelection();
Ext.each(selectedRecords, function(item) {
value +=item.get('groupId') +',';
}
);
Ext.Ajax.request({
url: SAVE_BULK_BOX_COMMENTS_URL,
method: 'POST',
params: {
groupIds :value,
positionDate: this.parentRecordData.data.positionDate,
boxStatus: fieldValues.boxStatus,
csrComment: fieldValues.csrComment
},
success: function(result, action, response) {
var jsonData = Ext.decode(result.responseText);
var jsonRecords = jsonData.records;
Ext.getCmp('boxCommentsWindow').close();
this.loadPositions();
},
scope: this
});
}
});

Creating multidimensional array inside each

I want to create a multidimensional array from the values I retrieved on an ajax post request.
API response
[{"id":"35","name":"IAMA","code":"24"},{"id":"23","name":"IAMB","code":"08"}]
jQuery code
var mulArr = [];
$.ajax({
type: 'POST',
url: '/path/to/APIendpoint',
dataType: 'json',
data: {
codes: codes
},
success: function(data) {
$.each(data, function(key, value) {
mulArr[key]['id'] = value.code;
mulArr[key]['text'] = value.name;
});
}
});
Syntax error
TypeError: mulArr[key] is undefined
I can properly fetch the data from the endpoint, the only error I encounter is the one I stated above. In perspective, all I want to do is simply a multidimensional array/object like this:
mulArr[0]['id'] = '24';
mulArr[0]['text'] = 'IAMA';
mulArr[1]['id'] = '08';
mulArr[1]['text'] = 'IAMB';
or
[Object { id="24", text="IAMA"}, Object { id="08", text="IAMB"}]
It happens because mulArr[0] is not an object, and mulArr[0]['id'] will throw that error. Try this:
var mulArr = [];
$.ajax({
type: 'POST',
url: '/path/to/APIendpoint',
dataType: 'json',
data: {
codes: codes
},
success: function(data) {
$.each(data, function(key, value) {
mulArr.push({id: parseInt(value.code), text: value.name});
// or try this if select2 requires id to be continuous
// mulArr.push({id: key, text: value.name});
});
}
});
Alternative to using push (which is a cleaner approach) is to define the new object.
mulArr[key] = {
id: value.code,
text:value.name
};
Another way of achieving what you want would be this one:
var mulArr = [];
$.ajax({
type: 'POST',
url: '/path/to/APIendpoint',
dataType: 'json',
data: {
codes: codes
},
success: function(data) {
mulArr = data.map(value => ({ id: parseInt(value.code), text: value.name }));
}
});
This is cleaner and also uses builtin map instead of jQuery $.each. This way you also learn the benefits of using the map function (which returns a new array) and also learn useful features of ES2015.
If you cannot use ES6 (ES2015) here is another version:
mulArr = data.map(function (value) {
return {
id: parseInt(value.code),
text: value.name
};
});
I guess you can already see the advantages.

jQuery autocomplete for json data

I am returning array of strings from controller to ajax call. trying to set to textbox those values. in textbox it is not populating. but I can see data in success method.
[HttpGet]
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public JsonResult GetWorkNamesAutoPoplate(string companyName)
{
...
var newKeys = companyNameslst.Select(x => new string[] { x }).ToArray();
var json = JsonConvert.SerializeObject(newKeys);
return Json(json, JsonRequestBehavior.AllowGet);
}
JS
$(document).on('change', '[name="FindCompanyName"]', function () {
$('[name="FindCompanyName"]').autocomplete({
source: function (request, response) {
$.ajax({
url: "GetWorkNamesAutoPoplate",
type: "GET",
dataType: "json",
data: { companyName: $('[name="FindCompanyName"]').val() },
success: function (data) {
alert(JSON.stringify(data));
response($.map(data, function(item) {
console.log(item);
return {
value: item
}
}));
}
});
},
messages: {
noResults: "", results: ""
}
});
});
alert(JSON.stringify(data)); display like this.
How to populate this data in textbox
The return type of your json is an array of arrays, i think you should return it as an array
var newKeys = companyNameslst.ToArray();
also, your data are serialized twice,
one from line,
var json = JsonConvert.SerializeObject(newKeys);
and second time from JsonResult action filter
return Json(json, JsonRequestBehavior.AllowGet);
sending json data like,
return Json(newKeys, JsonRequestBehavior.AllowGet);
instead of
var json = JsonConvert.SerializeObject(newKeys);
return Json(json, JsonRequestBehavior.AllowGet);
should work.
hope this helps.
This may resolve your issue :
success: function (data) {
alert(JSON.stringify(data));
if (data != null) {
response(data.d);
}
}
Also this link might help you to get some information :How to use source: function()... and AJAX in JQuery UI autocomplete

Passing an array of Javascript classes to a MVC controller?

I am trying to pass an array of services to my controller.
I've tried a bunch of different ways to get it work, serializing the data before going to controller, serializing each service, only thing that seems to work is changing the controller parameter to string and serializing array, then using JsonConvert, but I'd rather not do that.
With the specified code, I am getting the correct number of items in the List, but they all contain a service id with an empty guild, and service provider id is null.
Any ideas?
Javascript
function ServiceItem() {
this.ServiceProviderID = 'all';
this.ServiceID = '';
}
var selecteditems= (function () {
var services = new Array();
return {
all: function() {
return services;
},
add: function(service) {
services.push(service);
}
};
})();
var reserved = [];
$.each(selecteditems.all(), function(index, item){
reserved.push({ ServiceID: item.ServiceID, ServiceProviderID: item.ServiceProviderID});
});
getData('Controller/GetMethod', { items: reserved }, function(result) {
});
var getData = function (actionurl, da, done) {
$.ajax({
type: "GET",
url: actionurl,
data: da,
dataType: "json",
async: true,
success: function (d) {
if (typeof (done) == 'function') {
var str = JSON.stringify(d);
done(JSON.parse(str));
}
}
});
};
Controller
public JsonResult GetMethod(List<CustomObject> items)
{
}
Custom Object
public class CustomObject
{
public Guid ServiceID {get;set;}
public Guid? ServiceProviderID {get;set;}
}
Set the content-type and use POST instead of GET (as it is a list of complex type objects). mark your action with HttpPost attribute too.
See if this works:-
$.ajax({
type: "POST",
url: actionurl,
data: JSON.stringify(da),
dataType: "json",
contentType: 'application/json',
async: true,
success: function (d) {
if (typeof (done) == 'function') {
var str = JSON.stringify(d);
done(JSON.parse(str));
}
}
});

Jquery post to Action with Dictionary Parameter

I am feeling dejavu, but I cannot find the answer to this:
I have an array of objects that needs to look like this when inspecting a jQ $.post call:
limiter[0].Key
limiter[0].Value
so that it is mapped in the action
public ActionResult SomeAction(Dictionary<Guid, string> dictionary) { }
However, this javascript:
// Some Guid and Some Value
var param = [ { 'Key' : '00000000-0000-00000-000000', 'Value': 'someValue' } ];
$.post('/SomeController/SomeAction/',
{
dictionary: limiter,
otherPostData: data
},
function(data) {
callback(data);
}
)
produces this when inspecting it in firebug:
limiter[0][Key] = someKey // Guid Value
limiter[0][Value] = someValue
This is in jq 1.4.2. I seem to remember some flag you need to set to render json a different way in jQ. Does this ring any bells?
Try like this:
var param = {
'[0].Key': '28fff84a-76ad-4bf6-bc6d-aea4a30869b1',
'[0].Value': 'someValue 1',
'[1].Key': 'd29fdac3-5879-439d-80a8-10fe4bb97b18',
'[1].Value': 'someValue 2',
'otherPostData': 'some other data'
};
$.ajax({
url: '/Home/SomeAction/',
type: 'POST',
data: param,
success: function (data) {
alert(data);
}
});
should map to the following controller action:
public ActionResult SomeAction(Dictionary<Guid, string> dictionary, string otherPostData)
{
...
}
var dict = {}
dict["key1"] = 1
dict["key2"] = 2
dict["key3"] = 3
$.ajax({
type: "POST",
url: "/File/Import",
data: dict,
dataType: "json"
});
public void Import(Dictionary<string, int?> dict)
{
}
just send your obj as dataType: "json"
You can use this flag -
jQuery.ajaxSetting.traditional = true;
To get jQuery to post the data in a different format to the one you are seeing. See this question for further info -
Passing arrays in ajax call using jQuery 1.4
You will see the post param as limiter[0][Key] because jquery serializes the json data before it posts it. This is very well interpreted by the controller action and you get the required input in the action.
You can also use a list of objects and the result will be the same as what you wanted. This is a nice example.
http://www.mikesdotnetting.com/Article/96/Handling-JSON-Arrays-returned-from-ASP.NET-Web-Services-with-jQuery

Categories

Resources