I use a $resource to get data from the Server calling an ASP.NET MVC controller from my angular controller. The value (of type decimal?) is correctly returned from the MVC Controller, but when the promise is resolved, its parameter is just an empty object and not the expected value.
$resource file:
angular
.module('app')
.service('datacontext', function ($rootScope, $resource) {
return {
emissions: $resource('/api/emissions/:id', { 'id': '#id', emissionId: '#emissionId' },
{
create: { method: 'POST' },
lock: { method: 'PUT', url: "/api/emissions/lock" },
getFxRate: { method: 'GET', isArray: false, url: '/api/emissions/getfxrate'}
})
}
ASP.NET MVC Controller
[HttpGet]
[Route("/api/emissions/getfxrate")]
public async Task<IHttpActionResult> GetFxRate(string currency)
{
var res = await _emissionsAppService.GetFxRateAsync(currency);
//Here I get properly a decimal value as expected. (eg. 1.07123)
return Ok(res);
}
Angular Controller:
function getRate(currency){
datacontext.emissions.getFxRate({ currency: currency})
.$promise.then(function (result) {
//Here result is just an empty object {}
}
}
I cannot understand what is missing to get back the value form the server to the client controller.
The resolved promise was empty as a JSON object is expected, while I was returning a primitive value.
I could fix it by adding the following code to my $resource. As soon as I was returning an object, I could grab the value correctly inside the promise:
getFxRate: {
method: 'GET',
isArray: false,
url: '/api/emissions/getfxrate',
transformResponse: function (data) {
return { fxRate: data };
}
}
Related
$http({
method: 'GET',
dataType: 'json',
url: 'Calendar/GetDate',
params: { calenderId: $scope.CalendarId, fyYear: new Date(viewValue).toUTCString()
}
}).success(function (result) {
alert(result);
});
Below value getting returns, and its not calling the controller method
[UMAuthorize]
public ActionResult GetDate(string calenderId, DateTime fyYear)
{
.......
.....
return Json(new { startDate }, JsonRequestBehavior.AllowGet);
}
You are posting data to controller so I guess you should put the attribute HttpPost as shown below :-
[UMAuthorize]
[HttpPost]
public ActionResult GetDate(string calenderId, DateTime fyYear)
{
.......
.....
return Json(new { startDate }, JsonRequestBehavior.AllowGet);
}
and from you are calling controller make it a Post method instead of Get as shown below :-
$http({
method: 'POST',
dataType: 'json',
url: 'Calendar/GetDate',
params: { calenderId: $scope.CalendarId, fyYear: new Date(viewValue)
}
}).success(function (result) {
alert(result);
});
and ur fyYear object is DateTime in controller but you are converting it into string and then sending so its not matching the parameters of controller
I susupect the the url passed is wrong, use Url.Action() helper for generating correct url:
change:
url: 'Calendar/GetDate'
to:
url: '#Url.Action("GetDate","Calendar")'
I am trying to create a modal that will tell the user their submission was successfully submitted. This works fairly well, but the only problem is I have to declare each of my properties and assign it a value, then in the Json method I have accept all those parameters then do something with them. Is there any way to do this with a ViewModel? Or any otherway that this can be done using a ViewModel?
controller:
public Json Send(string var1, string var2)
{
...
if(valid)
return new Json(true, JsonRequestBehavior.AllowGet);
else
return new Json(false, JsonRequestBehavior.AllowGet);
}
javascript:
function submitData() {
$.ajax({
url: "/Report/Send",
type: "POST",
dataType: "json",
data: { var1 = Model.var1, var2 = Model.var2... },
success: function (data) {
if(data) {
showDialog();
}
else {
$("#errorDiv").load('Report/Error/');
}
},
error: function (somefunction) { }
});
}
Yes, create a ViewModel POCO class:
var myJsonResult = new { result: true };
return Json(myJsonResult);
You can also use a strongly typed ViewModel and return that:
var myJsonResult = new CustomResult { result: true };
return Json(myJsonResult);
Then just check that property on the class in your success function:
success: function (data) {
if(data.result) {
showDialog();
}
else if(!data.result) {
$("#errorDiv").load('Report/Error/');
}
},
EDIT:
You might also want to look at jquery's .serialize() method:
data: $("#myForm").serialize()
This will be useful if you bind your ViewModel to form elements and need to post them back to the server.
I am trying to use this following function to get some data.
function SaveData() {
var value = $('#tblRadio').find('input[type="radio"]:checked').val();
$.ajax({
type: "POST",
url: '/home/IsEmployeeVoted',
success: function (result) {
alert(result); // shows whole dom
if (parseInt(result) > 0) {
$('div.dvVoteWrapper').removeAttr('style');
$('div.popupArea').removeAttr('style');
}
else {
window.location = '/home/EmployeeVote?regoinID='+ value;
}
},
error: function () {
alert("Sorry, The requested property could not be found.");
}
});
}
The controller function:
public ActionResult EmployeeVote(string regionID)
{
}
regionId keep coming null to me though the value variable have some value in javascript. any ideas ??
Change
data: 'regionID=' + value,
to
data: {regionID: value},
You need to pass the data as an object literal. Another option (which I dont recommend), which is closer to your idea:
url: '/home/IsEmployeeVoted?regoinID=' + value,
But if you want this to work you would need to remove the type: 'POST' (since GET is the default type).
Few issues:
var value = $('#tblRadio').find('input[type="radio"]:checked').val();
I'd make sure that value is not undefined/null.
use alert(value) before the ajax call.
Also you are specifying GET but POSTING data to the server.
You could also wrap the regionId inside a javascript object, for instance.
$.ajax({
type: "POST",
data: { regionID: value },
url: '/home/IsEmployeeVoted',
success: function (data) {
alert(data); // shows whole dom
if (parseInt(data) > 0) {
$('div.dvVoteWrapper').removeAttr('style');
$('div.popupArea').removeAttr('style');
}
else {
window.location = "/home/EmployeeVote";
}
},
error: function () {
alert("Sorry, The requested property could not be found.");
}
});
I'm new to Ajax and I'm trying to disable a checkbox if certain items are selected in a dropdown. I need to pass in the mlaId to the GetMlaDeliveryType(int Id) method in the RecipientsController.cs.
I'm not exactly sure how to set up the ajax call in the javascript function checkMlaDeliveryType(mlaId).
// MLA Add disable express checkbox if delivery type is electronic
$('.AddSelectedMla').change(function () {
var deliveryType = checkMlaDeliveryType($('.AddSelectedMla').val());
// disable express option if delivery type is Electronic
if (deliveryType == "Mail") {
$(".mlaExpressIndicator").removeAttr("disabled");
}else{
$(".mlaExpressIndicator").attr('checked', false).attr("disabled", true);
}
})
// ajax call to get delivery type - "Mail" or "Electronic"
function checkMlaDeliveryType(mlaId)
{
$.ajax({
type: "GET",
url: "/Recipients/GetMlaDeliveryType/" ,
data: mlaId,
dataType: ,
success:
});
}
RecipientsController.cs
public string GetMlaDeliveryType(int Id)
{
var recipientOrchestrator = new RecipientsOrchestrator();
// Returns string "Electronic" or "Mail"
return recipientOrchestrator.GetMlaDeliveryTypeById(Id);
}
EDIT:
Here's how the final javascript looked that worked
// MLA Add disable express checkbox if delivery type is electronic
$('.AddSelectedMla').change(function () {
checkMlaDeliveryType($('.AddSelectedMla').val());
})
// ajax call to get delivery type - "Mail" or "Electronic"
function checkMlaDeliveryType(mlaId)
{
$.ajax({
type: 'GET',
url: '#Url.Action("GetMlaDeliveryType", "Recipients")',
data: { id: mlaId },
cache: false,
success: function (result) {
// disable express option if delivery type is Electronic
if (result == "Mail") {
$(".mlaExpressIndicator").removeAttr("disabled");
} else {
$(".mlaExpressIndicator").attr('checked', false).attr("disabled", true);
}
}
});
}
$.ajax({
type: 'GET',
url: '/Recipients/GetMlaDeliveryType',
data: { id: mlaId },
cache: false,
success: function(result) {
}
});
then fix your controller action so that it returns an ActionResult, not a string. JSON would be appropriate in your case:
public string GetMlaDeliveryType(int Id)
{
var recipientOrchestrator = new RecipientsOrchestrator();
// Returns string "Electronic" or "Mail"
return Json(
recipientOrchestrator.GetMlaDeliveryTypeById(Id),
JsonRequestBehavior.AllowGet
);
}
Now your success callback will directly be passed a javascript instance of your model. You don't need to specify any dataType parameters:
success: function(result) {
// TODO: use the result here to do whatever you need to do
}
Set data in the Ajax call so that its key matches the parameter on the controller (that is, Id):
data: { Id: mlaId },
Note also that it's a better practice to use #Url.Action(actionName, controllerName) to get an Action URL:
url: '#Url.Action("GetMlaDeliveryType", "Recipients")'
I have a controller method
[HttpPost]
public ActionResult GetUserData()
{
return Json(GetCurrentUser());
}
I'm calling it $.ajax() through a method like this:
ServerCall: function (method, args, callback) {
$.ajax({
type: 'POST',
url: method,
data: JSON.stringify(args),
contentType: 'application/json;charset=utf8',
dataType: 'json',
success: function (result) {
if (callback) {
callback(result);
}
},
error: function (err) {
}
});
}
with the call being:
ServerCall('GetUserData', null, function(data){
});
As it is, when I make this call, $.ajax returns with success, but 'data' is null. Debugging, responseText is empty. On the server side, GetUserData is called, and it is returning a properly formatted Json object (I've gone so far as to create my own JSON ActionResult and verified that data is indeed being written to the response stream.
If I add a dummy parameter to the server side method:
[HttpPost]
public ActionResult GetUserData(string temp)
{
return Json(GetCurrentUser));
}
everything works perfectly. Browser is IE8. My question is, can anyone explain why this is happening?
UPDATE:
Note workaround solution below: I'd still be interested in knowing the root cause.
No repro.
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult GetUserData()
{
return Json(new { foo = "bar" });
}
}
Index.cshtml view:
<script type="text/javascript">
var serverCall = function (method, args, callback) {
$.ajax({
type: 'POST',
url: method,
data: JSON.stringify(args),
contentType: 'application/json;charset=utf8',
dataType: 'json',
success: function (result) {
if (callback) {
callback(result);
}
},
error: function (err) {
}
});
};
serverCall('#Url.Action("GetUserData")', null, function (data) {
alert(data.foo);
});
</script>
result: 'bar' is alerted (as expected).
I was able to reproduce using Darin's code in IE8. While I don't know the root cause, I think it has something to do with how IE8 JSON.stringify handles null. Changing
data: JSON.stringify(args)
to
data: args ? JSON.stringify(args) : null
fixed the problem.
Note, the problem is intermittent - I was seeing failures in about one out of every ten calls. With the change, over 100 tests, the failure rate was zero.