Sean P
Sean P

Reputation: 949

How to Redirect with MVC when calling $post in angular

So upfront, I am new to angular so I am a little lost with how I want to accomplish a redirect after I post data back to a server:

I have the following in a update:

     $http.post("@Url.Action("SaveBranding", "AirlineConfig")", brandModel.model);

Then on the server I have this in my controller:

[HttpPost]
    public ActionResult SaveBranding(BrandingViewModel viewModel)
    {
        if (IsModelStateValid())
        {
            var airline = GetAirlineFromAirlinePlatformId(viewModel.AirlinePlatformId);

            switch (viewModel.PostAction)
            {
                case "Save":
                    BrandingViewModel.SaveEntity(viewModel, _db);
                    var airlineBranding = BrandingViewModel.FromEntity(_db.AirlinePlatforms.Single(x => x.AirlinePlatformId == viewModel.AirlinePlatformId).BrandingViews, viewModel.AirlinePlatformId);

                    return View("Branding", airlineBranding);
                case "Save & Close":
                    BrandingViewModel.SaveEntity(viewModel, _db);                     

                    return RedirectToAction("Edit", "AirlineConfig", new { id = airline.AirlineId });
                case "Cancel":
                    return RedirectToAction("Edit", "AirlineConfig", new { id = airline.AirlineId });
                default:
                    return HttpNotFound();
            }
        }
        return View("Branding"); //Replace this later
    }

My routing isnt working and I am lost how to do this so I can navigate to the correct location.

Upvotes: 2

Views: 4267

Answers (2)

Callum Linington
Callum Linington

Reputation: 14417

The angular way to redirect is using $location service.

angular.module('someModule', [])
    .controller('SomeController', ['$scope', '$http', '$location', someController])

function someController($http, $location) {
    $scope.brandModel = {};

    $scope.submit = function () {
        $http.post("@Url.Action("SaveBranding", "AirlineConfig")", brandModel.model).then(function (data) {
            $location.path('/url/to/path');
        });
    }
}

I put this answer here for completeness. I think also $location is more geared up for handling either hash urls or html5mode urls. If you use raw JavaScript, then you either use window.location.hash = "someUrl" or window.location.href = "someUrl". That could be a little caveat for not doing it the "angular" way.

I noticed also that you include that @Url.Action("", ""), when I did my Angular app with MVC in the index page I did this:

angular.module('someModule', [])
    .factory('urlService', urlService)

function urlService() {
    var service = {
        getSaveBrandingUrl: getSaveBrandingUrl
    };

    return service;

    function getSaveBrandingUrl() {
        return '@Url.Action("", "")';
    }
}

That way I can have all my other scripts separate, and they only rely on a function name so if you change the URL you don't have to go around the app changing all the links. When you inject this into the controller you would do something like:

angular.module('someModule', [])
    .controller('SomeController', ['$scope', '$http', '$location', 'urlService', someController])

function someController($scope, $http, $location, urlService) {
    $scope.brandModel = {};

    $scope.submit = function () {
        $http.post(urlService.getSaveBrandingUrl(), brandModel.model).then(function (data) {
            $location.path('/url/to/path');
        });
    }
}

Obviously then you can tie all that up into it's own service to reduce the injection into the controller:

angular.module('someModule', [])
    .factory('someControllerService', ['$http', 'urlService', someControllerService]) 
    .controller('SomeController', ['$scope', '$location', 'someControllerService', someController])

function someController($scope, $location, someControllerService) {
    $scope.brandModel = {};

    $scope.submit = function () {
        someControllerService.saveBranding($scope.brandModel.model).then(function (data) {
            $location.path('some/url');
        });
    }
}

function someControllerService($http, urlService) {
    var service = {
        saveBranding: saveBranding
    };

    return service;

    function saveBranding(branding) {
        return $http.post(urlService.getSaveBrandingUrl(), brandModel.model).then(function (data) {
            return data.data;
        });
    }
}

Upvotes: 1

Phil Degenhardt
Phil Degenhardt

Reputation: 7274

Use window.location to manually redirect in the browser rather than use a server redirect.

Upvotes: 2

Related Questions