using json in mvc 5 controller method - javascript

var checkboxes = $("input[type='checkbox']");
$(function ()
{
function getValueUsingClass() {
/* declare an checkbox array */
var chkArray = [];
/* look for all checkboes that have a class 'chk' attached to it and check if it was checked */
$(".chk:checked").each(function () {
chkArray.push($(this).val());
});
/* we join the array separated by the comma */
var selected = chkArray.join(",") + ",";
/* check if there is selected checkboxes, by default the length is 1 as it contains one single comma */
if (selected.length > 1)
{
$.ajax({
url: "/StateController/MyResult",
contentType: "application/json; charset=utf-8",
dataType: "json",
traditional: true,
type: "POST",
data: {"randstuff": chkArray},
success: function () {
// do things upon success
},
error: function () {
alert("Error!");
}
});
}
else
{
alert("Please check at least one of the checkbox");
}
}
$("#Charter").click(function () {
getValueUsingClass();
});
});
My Javascript code.
This gets me the Id of the checked boxes, i want to send this data to my controller, so that i can use it to select those particular values from my database. This is my first time using Jquery and Ajax, i have managed to get this far but i'm still quite lost.
public JsonResult MyResult(int[] randstuff)
{
return Json();
}
I know i'm meant to have a method like this to receive the data from the script file, but i'm not really sure how to go about that. I want to create an array from the received Json data, which i can then use to loop through my database and select only values who have matching Ids that are in the array.

I think there's a bit of extra fluff in your code, and that it can be cleaned up. Let's take a look at getValueUsingClass (see my comments in the code itself):
function getValueUsingClass() {
// no need for looping and building the array manually, we've got .map() for that
var chkArray = $('.chk:checked').map(function() {
return this.value;
}).get(); // turn into basic array
// check if the chkArray has any elements, don't build a string
if (chkArray.length > 1) {
$.ajax({
url: '#Url.Action("MyResult", "StateController")', // let MVC build URL for you
contentType: "application/json; charset=utf-8", // type sending
dataType: "json", // type receiving
// traditional: true, // not necessary
type: "POST",
data: JSON.stringify({ 'randstuff': chkArray }), // serialization
}).done(function () { // use jQuery promises
// do things upon success
}).fail(function () { // use jQuery promises
alert("Error!");
});
} else {
alert("Please check at least one of the checkbox");
}
}
Now, MVC should be able to deserialize your JSON request into the int[] array in your controller method, as long as it allows POSTing via the presence of an HttpPostAttribute:
[HttpPost]
public JsonResult MyResult(int[] randstuff)
{
return Json();
}

Related

AJAX - Wait for data to append before looping next

I am creating a drop down list in JavaScript, I am loading the data via Ajax and JSON, at the moment my code loops through a set of departments and runs into the ajax call in each iteration.
My problem is that my data seems to be appending in a random order, its likely that its loading in the order of whichever loads quickest.
I want to be able to loop through my Ajax call and append the data in the order that I declare (for each department).
is this something that can be done?
Here is my code:
//-- Ajax --
var departments = ['Accounts', 'Commercial', 'Installation', 'Production', 'Sales'];
var i;
for (i = 0; i < departments.length; i++) {
$.ajax({
type: "POST",
url: "Default.aspx/EmployeesDropDown",
data: '{X: "' + departments[i] + '"}',
contentType: "application/json; charset=utf-8",
dataType: "text json",
async: true,
success: createdropdown,
failure: function () {
alert("FAIL!");
}
});
}
//-- Creates dropdown --
function createdropdown(data) {
...appends all the data to my drop down list...
}
Any help or advice is appreciated, thank you in advance.
EDIT: This question is different from the related ones because I need to be able to loop through the string array, rather than just iterating based on numbers.
If you want to load the departments in the order they appear in the departments array you could load them one by one, waiting for each ajax request to finish until you start the next request.
Here is an example:
var departments = ['Accounts', 'Commercial', 'Installation', 'Production', 'Sales'];
var i = 0;
function reqDep(department) {
/*
Since i can't use ajax here let's use a promise.
*/
var p = new Promise(function(res, rej) {
setTimeout(function() {
res(department)
}, 1000)
})
return p;
// This is what you would actually do.
/*
var data = '{X: "' + department + '"}'
return $.ajax({
type: "POST",
url: "Default.aspx/EmployeesDropDown",
data: data,
contentType: "application/json; charset=utf-8",
dataType: "text json",
});
*/
}
function initDepartments(index) {
reqDep(departments[index])
// Here you would use `.done(function(data...`
// I am using `.then(function(data...`
// because of the promise.
.then(function(data) {
console.log(data)
if(i < departments.length) {
initDepartments(i)
}
})
i++;
};
initDepartments(i)

javascript, array of string as JSON

I'm having problems with passing two arrays of strings as arguments in JSON format to invoke ASMX Web Service method via jQuery's "POST".
My Web Method is:
[ScriptMethod(ResponseFormat=ResponseFormat.Json)]
public List<string> CreateCollection(string[] names, string[] lastnames)
{
this.collection = new List<string>();
for (int i = 0; i < names.Length; i++)
{
this.collection.Add(names[i] + " " + lastnames[i]);
}
return this.collection;
}
Now, the js:
function CreateArray() {
var dataS = GetJSONData(); //data in JSON format (I believe)
$.ajax({
type: "POST",
url: "http://localhost:45250/ServiceJava.asmx/CreateCollection",
data: dataS,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
//something
}
})
}
GetJSONData() is my helper method creating two arrays from column in a table. Here's the code:
function GetJSONData() {
//take names
var firstnames = $('#data_table td:nth-child(1)').map(function () {
return $(this).text();
}).get(); //["One","Two","Three"]
//take surnames
var surnames = $('#data_table td:nth-child(2)').map(function () {
return $(this).text();
}).get(); //["Surname1","Surname2","Surname3"]
//create JSON data
var dataToSend = {
names: JSON.stringify(firstnames),
lastnames: JSON.stringify(surnames)
};
return dataToSend;
}
Now, when I try to execude the code by clicking button that invokes CreateArray() I get the error:
ExceptionType: "System.ArgumentException" Message: "Incorrect first
JSON element: names."
I don't know, why is it incorrect? I've ready many posts about it and I don't know why it doesn't work, what's wrong with that dataS?
EDIT:
Here's dataToSend from debugger for
var dataToSend = {
names: firstnames,
lastnames: surnames,
};
as it's been suggested for me to do.
EDIT2:
There's something with those "" and '' as #Vijay Dev mentioned, because when I've tried to pass data as data: "{names:['Jan','Arek'],lastnames:['Karol','Basia']}", it worked.
So, stringify() is not the best choice here, is there any other method that could help me to do it fast?
Try sending like this:
function CreateArray() {
var dataS = GetJSONData(); //data in JSON format (I believe)
$.ajax({
type: "POST",
url: "http://localhost:45250/ServiceJava.asmx/CreateCollection",
data: {names: dataS.firstnames,lastnames: dataS.surnames} ,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
//something
}
})
}
This should work..
I think since you are already JSON.stringifying values for dataToSend property, jQuery might be trying to sending it as serialize data. Trying removing JSON.stringify from here:
//create JSON data
var dataToSend = {
names : firstnames,
lastnames : surnames
};
jQuery will stringify the data when this is set dataType: "json".
Good luck, have fun!
Altough, none of the answer was correct, it led me to find the correct way to do this. To make it work, I've made the following change:
//create JSON data
var dataToSend = JSON.stringify({ "names": firstnames, "lastnames": surnames });
So this is the idea proposed by #Oluwafemi, yet he suggested making Users class. Unfortunately, after that, the app wouldn't work in a way it was presented. So I guess if I wanted to pass a custom object I would need to pass it in a different way.
EDIT:
I haven't tried it yet, but I think that if I wanted to pass a custom object like this suggested by #Oluwafemi, I would need to write in a script:
var user1 = {
name: "One",
lastname:"OneOne"
}
and later pass the data as:
data = JSON.stringify({ user: user1 });
and for an array of custom object, by analogy:
data = JSON.stringify({ user: [user1, user2] });
I'll check that one later when I will have an opportunity to.

JavaScript: search user input in number of arrays

I am working with D3js library. On the web page, there is a search box which user can input their parameter. I receive arrays of data via Ajax post to my database. Following is the code:
..........
var aa;
var bb;
$(function(){
$.ajax({
type: "POST",
url: "http://localhost:7474/db/data/transaction/commit",
accepts: {json: "application/json"},
dataType: "json",
contentType: "application/json",
data: JSON.stringify(query), //query is somewhere above the code
//pass a callback to success to do something with the data
success: function (data) {
aa = data.results[0].data;
aa.forEach(function (entry) {
passVar(entry.row[0].name)
});}}
);
});
function passVar(smth){
bb =[smth];
console.log (bb);
//Should search the user input..........
}
//if the user input matches, filter function should run.........
function filterData() {
var value = d3.select("#constraint")[0][0].value;
inputValue = value;
............
}
As the result of console.log(bb)I receive the following on console:
["Direct Digital Control System"]
["Fire Protection"]
["HVAC Cooling- Waterside"]
["HVAC Heating- Waterside"]
["HVAC System"]
["HVAC-01"]
["HVAC-02"]
What I want to do:
If the user input match with one of the results in var bb, then program should run function filterdata() {....for querying. If not, don't do anything.
How should I write the code to make the search and run the other function? Thanks for the any help/suggestion.
You can loop through the array and find whether the user input is equals to the current index value of the array. if equals you can call your function and break the loop since no need to loop further more.
for(int i=0; i<bb.length; i++){
if(bb[i] == userInput){
filterdata();
break;
}
}

Display search results from API

Hello there I'm trying to create an app to search for recipes. I've tried using the Yummly API and BigOven api, but I can't get either to work.
here is the code i have for bigOven. I can't get any search results to appear in the "results".
$(function() {
$('#searchform').submit(function() {
var searchterms = $("#searchterms").val();
// call our search twitter function
getResultsFromYouTube(searchterms);
return false;
});
});
function getResultsFromYouTube (searchterms) {
var apiKey = "dvxveCJB1QugC806d29k1cE6x23Nt64O";
var titleKeyword = "lasagna";
var url = "http://api.bigoven.com/recipes?pg=1&rpp=25&title_kw="+ searchterms + "&api_key="+apiKey;
$.ajax({
type: "GET",
dataType: 'json',
cache: false,
url: url,
success: function (data) {
alert('success');
console.log(data);
$("#results").html(data);
}
});
}
Can anyone give me instructions on how to do this?? Thank you very much.
The API is returning JSON data, not HTML. I checked the API docs, and JSONP isn't necessary.
However, when you run this code:
$('#results').html(data);
Your code is going to just put the JSON into your HTML, and that isn't going to get displayed properly. You didn't say whether console.log(data) outputs the data correctly, but I'll assume it is.
So, you'll need to transform your JSON into HTML. You can do that programmatically, or you can use a templating language. There are a number of options, including underscore, jquery, mustache and handlebars.
I recommend handlebars, but it's not a straightforward bit of code to add (the main difficulty will be loading your template, or including it in your build).
http://handlebarsjs.com/
It would depend on you which key and values you have to show to your user's and in which manner... For ex. there is even an image link, you could either show that image to your user's or could just show them the image link...
Simple <p> structure of all the key's with there value's
jQuery
$.each(data.Results, function (key, value) {
$.each(value, function (key, value) {
$("#result").append('<p>Key:-' + key + ' Value:-' + value + '</p>');
});
$("#result").append('<hr/>');
});
Your ajax is working, you just need to parse the results. To get you started:
$.ajax({
type: "GET",
dataType: 'json',
cache: false,
url: url,
success: function (data) {
// Parse the data:
var resultsString = "";
for (var i in data.Results){
console.log( data.Results[i] );
resultsString+= "<div>"+data.Results[i].Title+ " ("+data.Results[i].Cuisine+")</div>";
}
$("#results").html(resultsString);
// If you want to see the raw JSON displayed on the webpage, use this instead:
//$("#results").html( JSON.stringify(data) );
}
});
I had created a little recursive function that iterates through JSON and spits out all of the values (I subbed my output for yours in the else condition) -
function propertyTest(currentObject, key) {
for (var property in currentObject) {
if (typeof currentObject[property] === "object") {
propertyTest(currentObject[property], property);
} else {
$('#results').append(property + ' -- ' + currentObject[property] + '<br />');
}
}
}
Then I called it within your AJAX success -
$.ajax({
type: "GET",
dataType: 'json',
cache: false,
url: url,
success: function (data) {
console.log(data);
propertyTest(data); // called the function
}
});
It spits out all of the data in the JSON as seen here - http://jsfiddle.net/jayblanchard/2E9jb/3/

wait for ajax result to bind knockout model

I have getGeneral function that calls ajax GET. When ajax recieves data (json), it creates KO model from given json and returns created KO.
When Knockout model is created and values are assigned, knockout applybindings should be called. Here is my code:
Defines GeneralModel and some related functions (inside "GeneralModel.js"):
var GeneralModel = function() {
//for now it is empty as data ar binded automatically from json
// CountryName is one of the properties that is returned with json
}
function getGeneral(pid) {
$.ajax({
url: "/api/general",
contentType: "text/json",
dataType: "json",
type: "GET",
data: { id: pid},
success: function (item) {
var p = new GeneralModel();
p = ko.mapping.fromJS(item);
return p;
},
error: function (data) {
}
});
}
This is called from another file (GeneralTabl.html), it should call get function and applyBindings to update UI:
var PortfolioGeneral = getGeneral("#Model.Id");
ko.applyBindings(PortfolioGeneral, document.getElementById("pv-portfolio-general-tab"));
However, in this scenario I am getting error (CountryName is not defined). This is because applyBindings happens before ajax returns data, so I am doing applyBindings to empty model with undefined properties.
Mapping from Json to Model happens here and is assignes values:
p = ko.mapping.fromJS(item);
I can also fill in GeneralModel with all fields, but it is not necessary (I guess):
var GeneralModel = function() {
CountryName = ko.observable();
...
}
It will still give an error "CountryName is not defined".
What is the solution?
1) Can I somehow move getGeneral inside GeneralModel, so get data would be part of GeneralModel initialization?
or
2) Maybe I should somehow do "wait for ajax results" and only then applyBindings?
or
I believe there are other options, I am just not so familiar with KO and pure JS.
Note: I fully understand that this is because Ajax is Async call, so the question is how to restructure this code taking into account that I have two seperate files and I need to call getGeneral from outside and it should return some variable.
Try using the returned promise interface:
function getGeneral(pid) {
return $.ajax({
url: "/api/general",
contentType: "text/json",
dataType: "json",
type: "GET",
data: {
id: pid
}
});
}
getGeneral("#Model.Id").done(function (item) {
var p = new GeneralModel();
p = ko.mapping.fromJS(item);
ko.applyBindings(p, document.getElementById("pv-portfolio-general-tab"));
}).fail(function () {
//handle error here
});

Categories

Resources