Parameters on controller always null when submitted via Angular - angularjs

I'm creating a js object with the same properties as my controller action expects as parameters.
controller.js
(function () {
'use strict';
angular
.module('app')
.controller('requestController', requestController);
requestController.$inject = ['$scope', 'lecturesFactory', 'attendeesFactory'];
$scope.setSelectedLectures = function () {
var lecture1, lecture2;
for (var i = $scope.lectures.length - 1; i >= 0; i--) {
var lecture = $scope.lectures[i];
if (lecture.selected === true) {
if (lecture1 == null) {
lecture1 = lecture.lectureId;
}
else {
lecture2 = lecture.lectureId;
}
}
}
attendeesFactory.setSelectedLectures($scope.emailAddress.text, lecture1, lecture2).then(function (data) {
$scope.showInvalidUserMessage = true;
$scope.message = data.message;
});
};
activate();
function activate() { }
}
})();
attendessFactory.js
(function () {
'use strict';
angular
.module('app')
.factory('attendeesFactory', attendeesFactory);
attendeesFactory.$inject = ['$http'];
function attendeesFactory($http) {
var service = {
setSelectedLectures: setSelectedLectures
};
return service;
function setSelectedLectures(emailAddress, lecture1, lecture2) {
var promise = $http({
method: 'POST',
url: '/Home/SetSelectedLectures',
data: {
emailAddress: emailAddress,
lecture1: lecture1,
lecture2: lecture2
}
}).then(function (response) {
console.log(response);
return response.data;
});
return promise;
}
}
})();
And my MVC Controller:
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
[HttpPost]
public IActionResult SetSelectedLectures(SelectedLectureData data)
{
// ...
}
}
public class SelectedLectureData
{
public String EmailAddress { get; set; }
public int Lecture1 { get; set; }
public int? Lecture2 { get; set; }
}
I've tried what some posts on StackOverflow suggested, such as using JSON.stringify, changing the content-type, but I still get the parameter values null (even if I put them directly in the action, instead of using a custom class).

Use [FromBody] anotation to make it working which will serialize data in SelectedLectureData model.
public IActionResult SetSelectedLectures([FromBody]SelectedLectureData data)
Otherwise you need to do
var promise = $http({
method: 'POST',
url: '/Home/SetSelectedLectures',
data: JSON.strigify({ "data": {
emailAddress: emailAddress,
lecture1: lecture1,
lecture2: lecture2
}})
})

Try updating your javascript to
function setSelectedLectures(emailAddress, lecture1, lecture2) {
var model = {
emailAddress: emailAddress,
lecture1: lecture1,
lecture2: lecture2
};
var data = JSON.strigify(model);
var promise = $http({
method: 'POST',
url: '/Home/SetSelectedLectures',
data: data
}).then(function (response) {
console.log(response);
return response.data;
});
return promise;
}
and using [FromBody] attribute on controller action
[HttpPost]
public IActionResult SetSelectedLectures([FromBody]SelectedLectureData data)
{
// ...
}

JSON property name should be same as class properties else it will take it as null
function setSelectedLectures(emailAddress, lecture1, lecture2) {
var promise = $http({
method: 'POST',
url: '/Home/SetSelectedLectures',
data: {
EmailAddress : emailAddress,
Lecture1: lecture1,
Lecture2: lecture2
}
}).then(function (response) {
console.log(response);
return response.data;
});

Related

How to call parameterized constructor from angular js controller through $http url?

I need to call Initailly the parameterized constructor from the angular js $http url that which maps the action method in MVC .
My angular js controller code is as follows:-
var app = angular.module("ourSiteLogIn", []);
app.controller("ourSiteLogInController", function ($scope, $http) {
$scope.GetLogInByUserIdPassword = function () {
$http({
method: "POST",
url: "User/GetLogInByUserIdPassword",
params: {
UserId: $scope.UserId,
Password: $scope.Password
}
}).then(function mySuccess(response) {
$scope.User = response.data;
}, function myError(reason) {
$scope.error = reason.data;
});
};
});
below is my controller :
public class UserController : Controller
{
private readonly ILogIn _login;
private readonly IExceptionLog _exceptionlog;
public UserController()
{
}
public UserController(ILogIn login, IExceptionLog exceptionLog)
{
_login = login;
_exceptionlog = exceptionLog;
}
[HttpPost]
public JsonResult GetLogInByUserIdPassword(string UserId, string Password)
{
try
{
Encrypt objEncrypt = new Encrypt();
tblLogIn objtblLogIn = new tblLogIn();
objtblLogIn = _login.GetLogInByUserIdPassword(UserId, objEncrypt.EncryptText(Password));
return Json(objtblLogIn, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
_exceptionlog.insertExceptionLog(ex);
return null;
}
}
}
here the problem is i am getting _login as null value while calling this method "GetLogInByUserIdPassword" and this method is presnt in another project. And by default it is calling default constructor but not calling the parameterized constructor. Any ideas will be appreciated.Thanks.

posting to an api with integer parameter not working with angularJs

I trying to post to a api with accepts an integer parameter using angular as below
function getDailyErrors() {
var uri = "/api/users/error-counts/";
var inData = { numberOfDays : 5}
return $http.post(uri, inData)
.then(function (response) {
return response.data;
});
}
API
[HttpPost]
[Route("api/users/error-counts/")]
public MultiCategorySeriesDto<int> GetErrorCounts(int numberOfDays=15)
{
return _uow.Events.Errors(numberOfDays);
}
for some reasons the API doesn't accept the parameter I passed instead takes the default int parameter.
May I know where the mistake is?
Try using a view model:
public class MyViewModel
{
public int NumberOfDays { get; set; }
}
that your controller action will take as parameter:
[HttpPost]
[Route("api/users/error-counts/")]
public MultiCategorySeriesDto<int> GetErrorCounts(MyViewModel model)
{
return _uow.Events.Errors(model.NumberOfDays);
}
As this is a POST, try using the [FromBody] attribute on the parameter to let the model binder know where to look for the data
[HttpPost]
[Route("api/users/error-counts/")]
public MultiCategorySeriesDto<int> GetErrorCounts([FromBody]int numberOfDays = 15)
{
return _uow.Events.Errors(numberOfDays);
}
The below code works fine for me, using the same API code as posted in your question.
global.Himanshu.ErrorServices.factory('errorcountservices', ['$q', '$http', function ($q, $http) {
return {getDailyErrors: fucntion() {
var deffered = $q.defer();
$http({
method: 'POST',
url:/api/users/error-counts/',
params: {
numberOfDays: 5
},
}).then(function (response) {
deffered.resolve(response.data);
},function (response) {
deffered.reject(response.data);
})
return deffered.promise;
}}

What is causing the model to null

Angular Service:-
app.service('loginService', ['$http', function ($http) {
this.userLogin = function (user) {
console.log(user); //prints {'username': 'username#gmail.com', 'password': 123'}
$http(
{
url: "/api/user/login",
method: "POST",
data: { 'model': user },
contentType: "application/json"
})
.then(function (data) {
if (data.status.toLower() === "success") {
return data;
}
else {
return null;
}
});
}
Angular Controller
app.controller('homeCtrl', ['$scope', 'loginService', function ($scope, loginService) {
$scope.login = function (user) {
debugger;
console.log($scope.user);
var data = loginService.userLogin($scope.user);
}
}]);
WebAPI.
[Route("api/user/login")]
public void Post([FromBody]LoginVM model)
{
if(ModelState.IsValid)
{
}
else
{
}
}
But when I debug the WebAPI model it has all the values as null.
My LoginVM class
[Required]
public string Username { get; set; }
[Required]
public string Password { get; set; }
Why I am getting the properties as null?
Your passing your content type header incorrectly. It get's passed as part of the headers parameter like so:
$http({
url: "/api/user/login",
method: "POST",
data: { 'model': user },
headers: {
"Content-Type": "application/json"
}
}).then(function (data) {
if (data.status.toLower() === "success") {
return data;
} else {
return null;
}
});
However, unless you have changed the default headers you don't even need to pass the content type. See the default headers in the documentation.
So you can simply make your request like so:
$http({
url: "/api/user/login",
method: "POST",
data: {
model: user
}
}).then(function (data) {
if (data.status.toLower() === "success") {
return data;
} else {
return null;
}
});
And you shouldn't need the [FromBody] Attribute on your method because your LoginVM is a complex type (Class).
Also, I've had it in the past where sometimes visual studio plays up and it's not debugging correctly. It's worth closing visual studio and re-opening it if that's the IDE you're using.

No action was found on the controller that matches the request angularjs GET

Can somebody please help me what am I missing or doing wrong. I am getting following error :
{"Message":"No HTTP resource was found that matches the request URI 'http://localhost:52096/api/Wotc/GetWotcDashBoardSummary?0=9&1=4&2=-&3=3&4=3&5=8&6=5&7=6&8=6&9=6'.","MessageDetail":"No action was found on the controller 'WotcAPI' that matches the request."}
wotcDashBoard.js :
var WotcDashBoardModule = angular.module('WotcDashBoardModule', []);
WotcDashBoardModule.factory('WotcDashBoardModuleService', ['$http', '$window', function ($http, $window) {
return {
GetDashBoardSummary: function (Ein) {
return $http({
url: '/api/Wotc/GetWotcDashBoardSummary',
method: 'GET',
params: Ein
});
}
};
}]);
WotcDashBoardModule.controller('WotcDashBoardController', ['$scope', 'WotcDashBoardModuleService', function ($scope, WotcDashBoardModuleService) {
var Ein = '00-00000';
WotcDashBoardModuleService.GetDashBoardSummary(Ein).then(function (response) {
$scope.Summary = response.data.Employees;
});
}]);
WotcAPIController :
[RoutePrefix("api/Wotc")]
public class WotcAPIController : ApiController
{
[HttpGet]
[Route("GetWotcDashBoardSummary")]
public async Task<IHttpActionResult> GetWotcDashBoardSummary(string Id)
{
CompanyWotcBO wotcSummary = new CompanyWotcBO();
try
{wotcSummary = await CompanyWotcBL.GetDashBoardSummary(Id);}
catch
{}
return Ok(new { WotcSummary = wotcSummary });
}
}
Route.config :
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Jobs",
url: "Jobs/{id}",
defaults: new { controller = "Jobs", action = "ShowJobPosting", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Account", action = "HomeInit", id = UrlParameter.Optional }
);
}
}
This is because there is a parameter name mismatch.
Changed params: Ein to params: { id: ein } in wotcDashBoard.js.
code :
return {
GetDashBoardSummary: function (Ein) {
return $http({
url: '/api/Wotc/GetWotcDashBoardSummary',
method: 'GET',
params: { id: ein }
});
}
};
There are few things which I think need's fix:
Firstly: instead of url: '/api/Wotc/GetWotcDashBoardSummary',it should be something like url: 'http://www.example.com/api/Wotc/GetWotcDashBoardSummary/id', where example.com is the domain where you have hosted your service.
Secondly:
[RoutePrefix("api/Wotc")]
public class WotcAPIController : ApiController
{
[HttpGet]
[Route("GetWotcDashBoardSummary/{id}")]
public async Task<IHttpActionResult> GetWotcDashBoardSummary(string Id)
{
CompanyWotcBO wotcSummary = new CompanyWotcBO();
try
{wotcSummary = await CompanyWotcBL.GetDashBoardSummary(Id);}
catch
{}
return Ok(new { WotcSummary = wotcSummary });
}
}
You might have to enable CORS after doing this if you get any Cross-origin-request errors.

Angular.js Uncaught SyntaxError: Unexpected Token :

I am using Angurlar.js to call my Web API and I am getting error as:
P01:1 Uncaught SyntaxError: Unexpected token : and in resources tab it is being shown that these braces should not be there {"ProductID1":"P01","ProductName1":"Pen","Quantity1":10,"Price1":12.0} kindly help me
this is my angular code:
var app = angular.module('store', []);
app.controller('StoreController', ['$http', '$scope', function ($http, $scope) {
$scope.display = function () {
// $http.get('http://localhost:17279/api/Product/GetProduct/' + $scope.pid).success(function (data) {
$http({
method: 'jsonp',
url: 'http://localhost:17279/api/Product/GetProduct/' + $scope.pid,
params: {
format: 'jsonp',
json_callback: 'JSON_CALLBACK'
}
}).success(function (data) {
{{data}}
});
}
}]);
below code is in my WebAPI controller
List<Product> productList = new List<Product>{
new Product{ProductID1="P01",ProductName1="Pen",Quantity1=10,Price1=12},
new Product{ProductID1="P02",ProductName1="Copy",Quantity1=12,Price1=20},
new Product{ProductID1="P03",ProductName1="Pencil",Quantity1=15,Price1=22},
new Product{ProductID1="P04",ProductName1="Eraser",Quantity1=20,Price1=27},
};
public List<Product> GetProductList()
{
return productList;
}
public IHttpActionResult GetProduct(string id)
{
var product = productList.FirstOrDefault(
(p) => p.ProductID1 == id);
if(product == null)
{
return NotFound();
}
return Ok(product);
}
Apart from this I have a product model class in WebAPI which has 4 members and their properties namely : price,quantity,productID,productname
Remove the {{data}} in your success callback. This is angular's way of binding expressions to view and should not be used within your javascript code
$scope.display = function () {
$http({
method: 'jsonp',
url: 'http://localhost:17279/api/Product/GetProduct/' + $scope.pid,
params: {
format: 'jsonp',
json_callback: 'JSON_CALLBACK'
}
}).then(function (data) {
$scope.data = data;
});
}

Resources