I have my angular controller defined like this for Put and Get method. I m new to angular JS. The get method works as expected but the Put method is not getting called. I followed one of the tutorial and implemented. though in the tutorial, they used REST service URL rather than controller method. I m using MVC controller here not the webAPI one.
public JsonResult GetEmployee(int id)
{
Employee empDetail = emp.GetEmployees().FirstOrDefault(i => i.EmpID == id);
return Json(empDetail, JsonRequestBehavior.AllowGet);
}
public JsonResult PutEmployee(int id, Employee updtEmp)
{
updtEmp.EmpID=id;
int index = emp.GetEmployees().FindIndex(i => i.EmpID == updtEmp.EmpID);
emp.GetEmployees().RemoveAt(index);
emp.GetEmployees().Add(updtEmp);
return Json(emp.GetEmployees(), JsonRequestBehavior.AllowGet);
}
Here is my angular Factory and controller method
myservice.factory('empFactory', function ($resource) {
return $resource('../../Employee/GetEmployee/:EmpID', { EmpID: '#EmpID' },
{
show: { method: 'GET' },
update: { method: 'PUT', params: { Employee: '#employee' } }
});
});
myApp.controller('empDetailController', function ($scope, empFactory, $routeParams) {
$scope.Employee = empFactory.show({ EmpID: $routeParams.EmpID });
$scope.UpdateEmp = function () {
// alert($scope.Employee.FirstName);
var employee=$scope.Employee;
empFactory.update({ EmpID: $routeParams.EmpID, Employee: employee })
};
});
Where did you mention in the MVC controller the method is PUT, Until and unless you mention the method type HttpPut or HttpPost etc., they are treated as HttpGet, Mention the method as PUT method in your MVC controller and try again.
Decorate your MVC PUT method like this :
[HttpPut]
public JsonResult PutEmployee(int id, Employee updtEmp)
{
updtEmp.EmpID=id;
int index = emp.GetEmployees().FindIndex(i => i.EmpID == updtEmp.EmpID);
emp.GetEmployees().RemoveAt(index);
emp.GetEmployees().Add(updtEmp);
return Json(emp.GetEmployees(), JsonRequestBehavior.AllowGet);
}
and factory and controller shouldbe like this :
myservice.factory('empFactory', function ($resource) {
var resource = {
employees:$resource('../../Employee/GetEmployee/:EmpID', { EmpID: '#EmpID' }),
empUpdateService:$resource('../../Employee/PutEmployee/:EmpID', { EmpID: '#EmpID' },{
update: { method: 'PUT', params: { Employee: '#employee' } }
})
};
return resource;
});
myApp.controller('empDetailController', function ($scope, empFactory, $routeParams) {
$scope.Employee = empFactory.employees.get({ EmpID: $routeParams.EmpID });
$scope.UpdateEmp = function () {
// alert($scope.Employee.FirstName);
var employee=$scope.Employee;
empFactory.empUpdateService.update({ EmpID: $routeParams.EmpID, Employee: employee })
};
You wanted to do it in a very good way, but for that you should use WEB Api controllers.
Web Api controller should be like this :
public class Employee : ApiController
{
public EmpModel GetEmployee(int id)
{
Employee empDetail = emp.GetEmployees().FirstOrDefault(i => i.EmpID == id);
return empDetail;
}
public bool PutEmployee(int id, Employee updtEmp)
{
updtEmp.EmpID=id;
int index = emp.GetEmployees().FindIndex(i => i.EmpID == updtEmp.EmpID);
emp.GetEmployees().RemoveAt(index);
emp.GetEmployees().Add(updtEmp);
return emp.PutEmployees(updtEmp);
}
public bool PostEmployee(Employee empModel)
{
// do something
return emp.SaveEmployees(empModel);
}
public bool DeleteEmployee(int id)
{
// do something
return emp.DeleteEmployees(id);
}
}
consider the below resource, that can do four operations. they are get, post, put and delete. :
var resource = {
employee: $resource('../../Employee/:EmpID', { EmpID: '#EmpID' },
{
update: { method: 'PUT' },
});
}
return resource;
use your resource in controllers like this, for get :
$scope.Employee = empFactory.employee.get({ EmpID: $routeParams.EmpID }).$promise;
for post :
$scope.SaveEmp = function (employee) {
empFactory.employee.save({
EmpID: $routeParams.EmpID,
Employee: employee
}, function (response) {
// do something with your success response
})
};
for Delete :
$scope.UpdateEmp = function () {
empFactory.employee.delete({
EmpID: $routeParams.EmpID
}, function (response) {
// do something with your success response
})
};
for update :
$scope.UpdateEmp = function (employee) {
empFactory.employee.update({
EmpID: $routeParams.EmpID,
Employee: employee
}, function (response) {
// do something with your success response
})
};
This is my service with multiple resource statements. Its close what you have initially shared as well
var resource = {
employee:
$resource('../../Employee/GetEmployee/:EmpID', { EmpID: '#EmpID' },
{
show: { method: 'GET' }
}),
empUpdate:
$resource('../../Employee/PutEmployee/:EmpID', { EmpID: '#EmpID', empval: '#empl' }, { update: { method: 'PUT', isArray: true } }),
empDelete:
$resource('../../Employee/DeleteEmployee/:EmpID', { EmpID: '#EmpID' }, { del: { method: 'DELETE', isArray: true } }),
empCreate:
$resource('../../Employee/CreateEmployee', { empval: '#empl' }, { create: { method: 'POST', isArray: true } })
}
return resource;
Now i have another problem that my angular js views are not updating and i posted it in stackoverflow. if you help it would be great
Angular JS CRUD update not refreshing
Related
I have Search View Where user enters Employee ID, Upon Clicking Button an Action Method is Executed and user is Redirected to Employee Details View.
If Employee Id not Matches I want to Retain the Same Search View and display a Label with Employee Details not Found Message in MVC,
Please help on doing the above Fucntionality in my Controller.
[HttpGet]
public async Task<ActionResult> Details(string firstName)
{
var empDetails = await _context.EmpDetails
.FirstOrDefaultAsync(m => m.FirstName == firstName);
if (empDetails == null)
{
// ???
}
return View(empDetails);
}
It is good practice to have ViewModel classes. Make one, and use it to transfer domain objects and messages to your view. Like this:
class EmpDetailsViewModel
{
public EmpDetail Emp { get;set; }
public string Message { get;set; }
}
[HttpGet]
public async Task<ActionResult> Details(string firstName)
{
var vm = new EmpDetailsViewModel();
var empDetails = await _context.EmpDetails
.FirstOrDefaultAsync(m => m.FirstName == firstName);
if (empDetails == null)
{
vm.Message = "Employee not found (or whatever)"
}
else
{
vm.Emp = empDetails;
}
return View(vm);
}
Then, in your view, just do
if (Model.Emp == null)
{
<span>#Model.Message</span>
}
else
{
<div>Emp details stuff </div>
}
What I understand is you want to return a message when Employee is not found.
Try this
[HttpGet]
public async Task<ActionResult> Details(string firstName)
{
var empDetails = await _context.EmpDetails
.FirstOrDefaultAsync(m => m.FirstName == firstName);
if (empDetails == null)
{
return Content("Employee not found");
}
return View(empDetails);
}
In view extract the message from the response.
--Edit
You can do an Ajax call like below to this action method
<script type="text/javascript">
$(function () {
$("#btnGetDetails").click(function () {
$.ajax({
type: "GET",
url: "/Employee/Details",
data: '{firstName: "' + $("#txtSearch").val() + '" }',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
alert(response.responseText);
},
failure: function (response) {
alert(response.responseText);
},
error: function (response) {
alert(response.responseText);
}
});
});
});
</script>
success call back will be triggered and the message will be available in the view. (Didn't test the script)
Hello i have a server side controller method:
public class CustomerController : ApiController
{
public void Delete(IList customers)
{
// handle delete action here....
}
}
I am using Angularjs , my question is how can i call my delete method from angularjs at client side.
Thanks
You could use an AJAX request with $http:
var customers = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Smith' }
];
$http({
method: 'DELETE',
url: '/customer',
data: customers
}).success(function(data, status, headers, config) {
alert('success');
}).error(function(data, status, headers, config) {
alert('error');
});
You should probably use $http in angularjs rather than normal http.
function Delete(customer) {
var promise = $http.post(
'/customer',
{ customer: customer}
).success(function (data, status, headers, config) {
return data;
}).error(function (data) {
return data;
});
return promise;
}
I need to call the following JsonResult method:
JsonResult Delete(int pubId)
{
try
{
using (var ctx = new LibsysLiteContext())
{
var p = ctx.Publishers.Find(pubId);
var allPublisher = ctx.Publishers.ToList();
ctx.Publishers.Remove(p);
var total = allPublisher.Count();
return Json(new { success = true, data = allPublisher, total = total }, JsonRequestBehavior.AllowGet);
}
return Json(new RestResult { Success = true, Data = entity, Message = "Country has been deleted" }, JsonRequestBehavior.DenyGet);
return null;
}
catch (Exception e)
{
return Json(new RestResult { Success = true, Message = e.Message }, JsonRequestBehavior.DenyGet);
}
}
from a js function (deleteRows):
var deleteRows = function () {
Ext.Msg.confirm(
'Delete Rows', 'Are you sure?',
function(btn) {
if (btn == 'yes') {
var hh = Ext.getCmp('gg').deleteSelected();
ajax({
//action and controller
url: '#Url.Action( "Publisher", "Delete")',
data: { "Id": Id },
type: 'POST',
dataType: 'json',
});
}
});
};
which is called by a handler of the following button:
X.Button().ID("bntdelete").Text("delete").Icon(Icon.Delete).Handler("deleteRows();"),
It didn't work at all this way! How can I move from client side to the server side from a JavaScript function?
In general calling a serverside [Direct Method] from js you use App.direct.<Method>();
Hopefully you have resolved this by now but in your ajax call you are defining the type as post but what you show on the controller is set as the default get. you need to add
[HttpPost]
public JsonResult Delete(int id)...
to your controller
I use Chosen plugin. I want to refresh Category (Chosen) dropdownlist, when change Section dropdownlist.
Here is view:
#model CategoryInputModel
#Html.DropDownListFor(model => model.SectionId, ViewBag.SectionList as IEnumerable<SelectListItem>, new { id = "SectionId" })
#Html.ListBoxFor(model => model.CategoryIdSet, ViewBag.AllCategoryList as MultiSelectList
, new
{
#class = "chzn-select",
data_placeholder = "Choose Categories...",
#style = "width : 500px;",
id = "CategoryIdSet"
})
CategoryInputModel is like:
public class CategoryInputModel
{
public string Name { get; set; }
public int SectionId{ get; set; }
public List<int> CategoryIdSet{ get; set; }
}
I can create cascade dropdownlist for simple lists, but could not create it for multiple select. I tried this :
<script type="text/javascript">
$(function () {
$("#SectionId").change(
function () {
loadLevelTwo(this);
});
loadLevelTwo($("#SectionId"));
});
function loadLevelTwo(selectList) {
var selectedId = $(selectList).val();
$.ajax(
{
url: "#Url.Action("GetCategoriesBySectionId", "Project")",
type: "GET",
data: { id: selectedId },
success: function (data) {
$("#CategoryIdSet").html($(data).html());
},
error: function (xhr) {
alert("Something went wrong, please try again");
}
});
}
</script>
In controller:
public ActionResult GetCategoriesBySectionId(int id)
{
var result = MyService.GetCategoriesBySectionId(id);
// **its problem to create partial view that return chosen dropdownlist I need**
}
How can I create cascade Chosen dropdownlist?
I think you need to add a little more to your ajax callback. I replaced success method with done. Try this, it works for me:
function loadLevelTwo(selectList) {
var selectedId = $(selectList).val();
$.ajax(
{
url: "#Url.Action("GetCategoriesBySectionId", "Project")",
type: "GET",
data: { id: selectedId },
error: function (xhr) {
alert("Something went wrong, please try again");
}
}).done(function (data) {
$("#CategoryIdSet").children().each(function (index, option) {
$(option).remove();
});
//blank option
var items = "<option selected value=\"\"></option>";
$.each(data,
function () {
items += "<option value=\"" + this[0] + "\">" + this[1] + "</option>";
});
$("#CategoryIdSet").html(items)
$("#CategoryIdSet").trigger("liszt:updated");
$("#CategoryIdSet").change();
});
}
controller action could look like this:
public ActionResult GetCategoriesBySectionId(int id)
{
var result = MyService.GetCategoriesBySectionId(id);
//build JSON.
var modelDataStore = from m in result
select new[] { m.YourValueProperty.ToString(),
m.YourTextProperty };
return Json(modelDataStore, JsonRequestBehavior.AllowGet);
}
I'm pretty new to MVC. I need to make ajax call to an Action with parameters using html.Action(). I'm unable to pass this..
Hope it will be helpful for other MVC begineers as well..
HTML:
<%: Html.ActionLink("Add Race", "AddRace",
new {eventId = Model.EventId, fleetId=Model.SelectedFleet.ID},
new{#onclick=string.Format("return checkFleetAddedandScroing()")}) %>
Jquery:
function checkFleetAddedandScroing() {
debugger;
$.ajax({
type: "GET",
url: '<%=Url.Action("CheckFleetExists")%>',
dataType: "json",
cache: false,
success: function (data, textStatus) {
data = eval("(" + data + ")");
if (data == true) {
return true;
}
else {
alert("Cannot Add race becasue you have not yet added any fleets and fleet scoring is checked.");
return false;
}
}, //success
error: function (req) {
}
});
}
Action:
public JsonResult CheckFleetExists(Guid fleetId )
{
bool exists = false;
try
{
exists = !db.Races.Any(r => r.FleetID == fleetId);
}
catch
{
}
return Json(exists, JsonRequestBehavior.AllowGet);
}
I need to pass fleetid to action which is in Model.SelectedFleet.ID. Its being used somewhere on pages. But i'm unable to use that somehow..
please suggest where i'm doing wrong...
It looks like you are trying to invoke a controller action using AJAX when the link is clicked and depending on the result of this call either allow the user to be redirected to the actual AddRace action or be prompted with an error message.
The problem with your code is that you are attempting to return true/false from within the success AJAX callback which doesn't make any sense. You need to always return false from the click callback and inside the success callback, depending on the returned value from the server, redirect manually using the window.location.href function.
HTML:
<%: Html.ActionLink(
"Add Race",
"AddRace",
new {
eventId = Model.EventId,
fleetId = Model.SelectedFleet.ID
},
new {
data_fleetid = Model.SelectedFleet.ID,
#class = "addRace"
}
) %>
Jquery:
<script type="text/javascript">
$(function () {
$('.addRace').click(function (evt) {
$.ajax({
type: 'GET',
url: '<%= Url.Action("CheckFleetExists") %>',
cache: false,
data: { fleetId: $(this).data('fleetid') },
success: function (data) {
if (data.exists) {
// the controller action returned true => we can redirect
// to the original url:
window.location.href = url;
}
else {
alert("Cannot Add race becasue you have not yet added any fleets and fleet scoring is checked.");
}
},
error: function (req) {
}
});
// we make sure to cancel the default action of the link
// because we will be sending an AJAX call
return false;
});
});
</script>
Action:
public ActionResult CheckFleetExists(Guid fleetId)
{
bool exists = false;
try
{
exists = !db.Races.Any(r => r.FleetID == fleetId);
}
catch
{
}
return Json(new { exists = exists }, JsonRequestBehavior.AllowGet);
}
Remark: inside your AddRace controller action don't forget to perform the same verification as you are doing inside your CheckFleetExists. The user could simply disable javascript and the AJAX call will never be done.
change your action like this :
public JsonResult CheckFleetExists(string fleetId)
{
var fleetGuid = Guid.Parse(fleetId);
bool exists = false;
try
{
exists = !db.Races.Any(r => r.FleetID == fleetGuid );
}
catch
{
}
return new JsonResult{ Data = exists};
}
and change you ActionLink so :
<%: Html.ActionLink("Add Race", "AddRace",
new {eventId = Model.EventId, fleetId=Model.SelectedFleet.ID},
new{onclick=string.Format("return checkFleetAddedandScroing({0})",Model.SelectedFleet.ID)}) %>
and your script block may look something like this :
function checkFleetAddedandScroing($fleetId) {
$.ajax({
type: "POST",
url: '<%=Url.Action("CheckFleetExists")%>',
dataType: "json",
data : { "fleetId" : $fleetId },
cache: false,
success: function (data, textStatus) {
data = eval("(" + data + ")");
if (data == true) {
return true;
}
else {
alert("Cannot Add race becasue you have not yet added any fleets and fleet scoring is checked.");
return false;
}
}, //success
error: function (req) {
}
});
}
Problem was in answers that url to action was not complete..i did it using this way
function checkFleetAddedandScroing() {
// debugger;
$.ajax({
type: "POST",
url: '<%=Url.Action("CheckFleetExists", new {eventId=Model.EventId})%>',
dataType: "json",
cache: false,
success: function (data, textStatus) {
data = eval("(" + data + ")");
if (data == true) {
return true;
}
else {
alert("Cannot Add race becasue you have not yet added any fleets and fleet scoring is checked.");
return false;
}
}, //success
error: function (req) {
}
});
}