Can Js and Model.findAll() unable to display data in UI - canjs

I have this code where i am trying to retrieve data from model.findall() and display in UI as table
model.js
define(['jquery', 'can'], function ($, can) {
var serviceModel = can.Model.extend({
findAll: function (params,servicename) {
return $.ajax({
type: 'POST',
dataType: 'JSON',
contentType: 'application/json',
url: 'data/+ servicename',
success: function (data) {
console.log("Success ");
},
error: function () {
console.log("Error");
}
});
}
}, {});
return serviceModel;
});
controller.js
serviceModel.findAll(params,"SP_table", function(data) {
if (data.status === "success") {
$('#idtable').dataTable().fnClearTable();
$('#idtable').dataTable().fnAddData(data.result);
}else{
alert("inside alert");
}
});
issue is in serviceModel.findAll() i am unable to get data inside serviceModel.findAll() because data is in the form of stored procedure or macro, which i am getting using "servicename" from function above
please let me know how to resolve this issue.

You can access the raw xhr data from the ajax call and convert it to an appropriate format by overriding the parseModels method:
https://canjs.com/docs/can.Model.parseModels.html
Overwriting parseModels If your service returns data like:
{ thingsToDo: [{name: "dishes", id: 5}] } You will want to overwrite
parseModels to pass the models what it expects like:
Task = can.Model.extend({ parseModels: function(data){ return
data.thingsToDo; } },{}); You could also do this like:
Task = can.Model.extend({ parseModels: "thingsToDo" },{});
can.Model.models passes each instance's data to can.Model.model to
create the individual instances.
In their example above, the response is a nested JSON: in yours, it is your procedure or macro. You have the opportunity here in parseModels to rewrite the response in the appropriate format.

Related

Make ajax call dependent on another ajax call

I would to avoid nesting a bunch of ajax calls inside the 'success' event of one another. I was wondering if someone could guide me in the right direction on how to do something like this? Where one ajax call is dependent on another's return value?
The getLoginAccess() function will be used in many other methods in a similar manner.
If the first one fails i would like to just have it return a 'null' value which i can then take into account before running the second ajax call. Below i demonstrate a psuedo example of what im trying to do.
The method getLoginAccess returns a dictionary of data that is required for the second method createItem to execute. So only if getLoginAccess returns valid data will createItem continue on to call the actual ajax call.
Thank you
function getLoginAccess() {
$.ajax({
url: '.../api/v1/auth/access_token',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json',
'Connection': 'keep-alive'
},
data: {
grant_type: 'client_credentials',
username: 'johnDoe',
password: '******'
},
success: function (data) {
console.log(JSON.stringify(data));
return data;
},
error: function (data) {
console.log(data);
return null;
}
})
}
function createItem() {
var login = getLoginAccess();
if (login == null) {
return false;
}
$.ajax({
url: '.../api/v1',
method: 'POST',
headers = {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'access': `${login.access_token}`
};
data: {},
success: function (data) {
console.log(JSON.stringify(data));
},
error: function (data) {
console.log(data);
}
})
}
window.onload = function(){
createItem();
};
If you want to refactor the part where the login is verified we could create an intermediate function .. something like this:
Your login function here
function getLoginAccess(){
// Return login data or null
}
Here we can create an intermediate function to deal with the dependencies of the next execution. If the login returns something other than null, the function passed as a parameter will be executed.
function intermediateFunction(functionName,login){
if(login){
window[functionName]();
}
}
Here are the other functions you have created.
function createItem() {
// Do something
}
function listItem() {
// Do something
}
Here instead of calling the createItem() function you call the intermediary
window.onload = function(){
intermediateFunction(getLoginAccess(), "createItem");
};
So basically you would always call the intermediate function that would check the login before calling a particular function. I believe that this is how I would refactor :)

Bypass Ajax request within javascript promise in Unit Testing

I have a function called getStudentData(),returns resolved data.
Inside getStudentData(), I have an Ajax request.
I want to Bypass Ajax request in my unit test case using Mocha , so that when i make a call to getStudentData(), the data should be returned.
Please find the code below:
getStudentData: function() {
return studentData || (studentData = new Promise(function(resolve, reject) {
var request = {
//request data goes here
};
var url = "/student";
$.ajax({
url: url,
type: "POST",
data: JSON.stringify(request),
dataType: "json",
contentType: "application/json",
success: function(response, status, transport) {
//success data goes here
},
error: function(status, textStatus, errorThrown) {
reject(status);
}
});
}).then(function(data) {
return data;
})['catch'](function(error) {
throw error;
}));
}
Please let me know how to Bypass Ajax request By stubbing data using sinon.js .so that when i make a call to getStudentData() , data should be returned.
First of all doing:
then(function(data){ return data; })
Is a no-op. So is:
catch(function(err){ throw err; });
Now, your code uses the explicit construction anti-pattern which is also a shame, it can be minimized to:
getStudentData: function() {
var request = {
//request data goes here
};
var url = "/student";
return studentData ||
(studentData = Promise.resolve($.ajax({
url: url,
type: "POST",
data: JSON.stringify(request),
dataType: "json",
contentType: "application/json" })));
}
Now, that we're over that, let's talk about how you'd stub it. I'd do:
myObject.getStudentData = function() {
return Promise.resolve({}); // resolve with whatever data you want to test
};
Which would let you write tests that look like:
it("does something with data", function() { // note - no `done`
// note the `return` for promises:
return myObj.getStudentData().then(function(data){
// data available here, no ajax request made
});
});
Although in practice you'll test other objects that call that method and not the method itself.

Checking all JSON values for a specific attribute/parameter

I am trying to check a JSON for the "start" object, and what it value is.
For example, if my AJAX is
$(document).ready(function () {
$.ajax({
url: "Content/events/document.json",
type: "GET",
success: function (resp) {
alert(JSON.stringify(resp)); //Stringify'ed just to see JSON data in alert
},
error: function () {
alert("failed");
}
});
});
and it returns
[
{"title":"Bi-weekly Meeting1","start":"2014-07-09","color":"red"},
{"title":"Bi-weekly Meeting2","start":"2014-08-06","color":"red"},
{"title":"Bi-weekly Meeting3","start":"2014-07-23","color":"red"},
{"title":"Test Event","url":"http://google.com/","start":"2014-07-28"}
]
How can I check every "start" value? and if it is today, store that event in a different array?
I just want to keep track of today's events and I am not sure how to iterate through a JSON Object.
Note you should set dataType: "json" so that JQuery will parse the ajax response coming back as JSON automatically. Then just iterate through the array you receive, like so:
function sameDay( d1, d2 ){
return d1.getUTCFullYear() == d2.getUTCFullYear() &&
d1.getUTCMonth() == d2.getUTCMonth() &&
d1.getUTCDate() == d2.getUTCDate();
}
$(document).ready(function () {
$.ajax({
url: "Content/events/document.json",
type: "GET",
dataType: "json",
success: function (resp) {
resp.forEach(function(item) {
console.log(item.start);
if (sameDay( new Date(item.start), new Date)){
// This one has today's date!
}
});
},
error: function () {
alert("failed");
}
});
});

How to handle FileStream return type in .ajax post?

I am sending JSON object through following code.. Controller returning values in CSV format that should be provide promt to open or save as CSV file. I unable to understand that what exactly code should be write in success: function (result)
Link for Export
Html.ActionLink("Export", "", "", null, new { #onclick = "return exportData();"})
function exportData() {
var searchViewModel = getExLogSearchModelData();
var path = getAbsolutePath("ExclusionLog", "ExportData");
$.ajax({
url: path,
cache: false,
contentType: 'application/json; charset=utf-8',
dataType: 'html',
type: 'POST',
data: JSON.stringify(searchViewModel),
success: function (result) {
},
error: function (error) {
$("#voidcontainer").html("Error");
}
});
}
Controller ActionResult
public ActionResult ExportData(ExclusionLogSearchViewModel postSearchViewModel)
{
try
{
IEnumerable<ExclusionLogViewModel> exclusionLogData = null;
exclusionLogcData = this._workerService.GetExclusionLogData(postSearchViewModel);
return CSVFile(exclusionLogMembershipSyncData.GetStream<ExclusionLogViewModel>(), "ExclusionLogTables.Csv");
}
catch (Exception ex)
{
throw ex;
}
return null;
}
Can you please suggest how to do this?
I've hit the same problem and I didn't find a way to download file using $.ajax but I found an excellent JavaScript library that provides similar behavior:
https://github.com/johnculviner/jquery.fileDownload
You just need to invoke something like this:
$.fileDownload(path, {
httpMethod: 'POST',
data: JSON.stringify(searchViewModel),
success: function (result) {
},
error: function (error) {
$("#voidcontainer").html("Error");
}
});
And remember to create cookie in controller. In src/Common there is suitable action filter that do it for you.

asp.net mvc ajax driving me mad

how come when I send ajax request like this everything works
$(".btnDeleteSong").click(function () {
var songId = $(this).attr('name');
$.ajax({
type: 'POST',
url: "/Home/DeleteSong/",
data: { id: songId },
success: ShowMsg("Song deleted successfully"),
error: ShowMsg("There was an error therefore song could not be deleted, please try again"),
dataType: "json"
});
});
But when I add the anonymous function to the success It always showes me the error message although the song is still deleted
$(".btnDeleteSong").click(function () {
var songId = $(this).attr('name');
$.ajax({
type: 'POST',
url: "/Home/DeleteSong/",
data: { id: songId },
success: function () { ShowMsg("Song deleted successfully"); },
error: function () {
ShowMsg("There was an error therefore song could not be deleted, please try again");
},
dataType: "json"
});
});
what if i wanted few things on success of the ajax call, I need to be able to use the anonymous function and I know that's how it should be done, but what am I doing wrong?
I want the success message to show not the error one.
function ShowMsg(parameter) {
$("#msg").find("span").replaceWith(parameter);
$("#msg").css("display", "inline");
$("#msg").fadeOut(2000);
return false;
}
Make sure your action is returning Json data.
"json": Evaluates the response as JSON and returns a JavaScript object. In jQuery 1.4 the JSON data is parsed in a strict manner; any malformed JSON is rejected and a parse error is thrown. (See json.org for more information on proper JSON formatting.)
http://api.jquery.com/jQuery.ajax/
Your action method should surely return Json data. I have the similar code see if that helps.
public ActionResult GetAllByFilter(Student student)
{
return Json(new { data = this.RenderPartialViewToString("PartialStudentList", _studentViewModel.GetBySearchFilter(student).ToList()) });
}
$("#btnSearch").live('click',function () {
var student = {
Name: $("#txtSearchByName").val(),
CourseID: $("#txtSearchByCourseID").val()
};
$.ajax({
url: '/StudentRep/GetAllByFilter',
type: "POST",
data: JSON.stringify(student),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function(result) {
$("#dialog-modal").dialog("close");
RefreshPartialView(result.data);
}
, error: function() { alert('some error occured!!'); }
});
});
Above code is used to reload a partial view. in your case it should be straight forward.
Thanks,
Praveen

Resources