2

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 })
    };
});
TechQuery
  • 253
  • 3
  • 17
  • Have you [enabled PUT in IIS for ASP.NET MVC](http://stackoverflow.com/questions/12440277/how-do-i-enable-http-put-and-delete-for-asp-net-mvc-in-iis)? – Jasen May 18 '15 at 17:26
  • Hi Jasen, i have enabled Put.. Please refer my comment in the below section – TechQuery May 18 '15 at 18:03
  • You'll need to decorate your controller with the appropriate verb `[HttpPut]` as MVC controllers don't map the action name to verb like WebAPI will. That means you'll need to set up your angular service with two requests with different URL instead of trying to overload a single one. – Jasen May 18 '15 at 18:15

3 Answers3

2

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 })
};
Konammagari
  • 364
  • 2
  • 8
  • I have included the put method. but the problem which i m seeing is , If you look at the URL, it points directly to the Get Method. So logically what i m thinking is, it should be like function myfactory(methodname) { If methodname==get { give the url and call show method} } return $resource('../../Employee/GetEmployee/:EmpID', { EmpID: '@EmpID' }, { show: { method: 'GET' }, update: { method: 'PUT', params: { Employee: '@employee' } } }); but i dont know how to do it in angular code – TechQuery May 18 '15 at 18:01
  • You better use web api controllers, they'll reduce lot of effort and they'll give you clean and simple URLs to access your REST api. Its just my suggestion. – Konammagari May 18 '15 at 18:07
  • Please find my response in the answer section – TechQuery May 18 '15 at 18:21
  • I have uploaded the code also which i have used. Thanks in advance for your response – TechQuery May 18 '15 at 18:22
  • Answer updated with factory and controller.have a look. – Konammagari May 18 '15 at 18:23
  • I updated my answer part below. we will continue further discussion there. Still the code which I updated below shows "couldn't find show method" – TechQuery May 18 '15 at 18:41
  • I need your help for this post [link](http://stackoverflow.com/questions/30339398/angular-js-success-callback/) – TechQuery May 20 '15 at 03:04
  • I updated my answer and also find my answer for the post [link](http://stackoverflow.com/questions/30339398/angular-js-success-callback/) – Konammagari May 20 '15 at 16:15
1

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
  })

};

Konammagari
  • 364
  • 2
  • 8
  • Thanks.. my condition working perfectly except for the fact, it uses different URL. I agree using webAPI is the best method. but wanted to fix tis one before taking this approach just to be aware of both methds. and it hurts to move on without actually fixing the issue. I don't know why employee.show not working and it shows method not found – TechQuery May 18 '15 at 18:54
  • now the prob turns out to be an issue with angular JS factory method. we need to found out a way of writing the factory with four different methods using $resource – TechQuery May 18 '15 at 18:55
  • Those four methods you use in controller, your factory will have only resource – Konammagari May 18 '15 at 18:58
  • then it turns out to me , we cannot use four resources in angularjs factory. This i couldnt take to my heart:(:( logically i think it has to work.... – TechQuery May 18 '15 at 19:06
  • Where did you see four methods in factory here @TechQuery – Konammagari May 19 '15 at 02:40
  • In case if we use Web API, it will have same URL method and your logic will perfectly work fine. But in case if we use MVC controllers, we have different urls for Put, POST, GET and DELETE. In that case, there should be four methods in a factory. I have written code which can have 4 different methods but here the challenge comes when each method contains return $resource – TechQuery May 19 '15 at 03:49
  • Right now, all I m looking for is merely a factory which contains different methods and each method returns a resource – TechQuery May 19 '15 at 03:50
  • I have got the working version. will share the updates tomo. Thanks a lot – TechQuery May 19 '15 at 04:07
  • please see my response in the next answer section – TechQuery May 19 '15 at 16:52
0

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

Community
  • 1
  • 1
TechQuery
  • 253
  • 3
  • 17