0

It's a fairly simple problem, I am using AngularJS v1.7.2 with C# MVC.

I got my standard setup with Layout pages and Views. I load my AngularJs controllers/services from external script files so there's nothing on the Views.

My problem is that I want to assign a value from ViewBag to a controller variable, but I obviously can't reference ViewBag in a script as it needs to be done on the cshtml page.

I have tried doing it inside ng-init like so

<div ng-init="City = @ViewBag.City"></div>

Or

<div style="visibility: hidden;">{{CityId = '1'}}</div>

I tried variations with {{City = @ViewBag.City}}, '@ViewBag.City' and couple of others I saw on StackOverflow to no avail.

I load my scripts on the view using:

@section Page_Scripts {
    @Scripts.Render("~/angular/ngListing")
}

That obviously is loaded in Layout. My controller works fine so that's not the issue.

My controller is making an ajax call upon initialization, at that point I need the $scope.City to be populated with the right value, however it's always set at 0.

Here's what my controller + service (combined for sake of SO) looks like:

_mainApp.controller("ListingCtrl", function ($scope, $http) {
    $scope.City = 0;
    $scope.Attractions = [];
    $scope.Offset = 0;
    $scope.Pages = new Array(10);

    var MakeRequest = function (offset) {
        $http.post("/City/GetStuff?City=" + $scope.City + "&Offset=" + offset).then(function (resp) {
            $scope.Attractions = resp.data;
        });
    }

    MakeRequest($scope.Offset);

    $scope.PageUp = function () {
        $scope.Offset++;
        MakeRequest($scope.Offset);
    }

    $scope.PageDown = function () {
        $scope.Offset--;
        MakeRequest($scope.Offset);
    }

    $scope.GoTo = function (offset) {
        $scope.Offset = offset;
        MakeRequest(offset);
    }

});

Any solution that is not hacky-ish would be appreciated. It can include directives or a way to assign a value to $scope.City but inline, or at least get my ViewBag.City value passed to the controller somehow.

6
  • I don't know how much of hack-ish this could sound to you, but you could try using a hidden value <input type"hidden" ng-model="city" value="@ViewBag.City" /> and then use $scope.city in the angularjs controller. Commented Jul 30, 2018 at 18:01
  • I tried this already, what I observed is that the value is displayed for few ms then it's set to 0 as per controller. Commented Jul 30, 2018 at 18:04
  • 1
    Oh, well, then try removing this line from controller $scope.City = 0; and in the input call the controller initialization logic, which is in this case MakeRequest like this: <input type"hidden" ng-model="city" value="@ViewBag.City" ng-init="MakeRequest(Offset)" />. Also make sure to load the scripts once the MVC values such as @ViewBag.City are ready to populate the input value. With this we do not assign the value of $scope.City in the controller but in the view. Commented Jul 30, 2018 at 18:09
  • @georgeawg Yes, I thought it would be that simple hence why I didn't post it on SO from the beginning and tried to fiddle with it. However upon making the $http request $scope.City is undefined. Commented Jul 30, 2018 at 18:10
  • Possibly because the MVC renderer hasn't fully rendered (and processed) all required values and the scripts start loading. Commented Jul 30, 2018 at 18:11

1 Answer 1

2

Use a function in the ng-init directive:

<div ng-init="initCity(@ViewBag.City)"></div>

Define the function in the controller:

$scope.initCity = function(city) {
    $scope.city = city;
    MakeRequest($scope.offset, $scope.city);
};

function MakeRequest(offset,city) {
    var url = "/City/GetStuff";
    var params = {city:city, offset:offset};
    var config = {params: params};
    $http.get(url,config).then(function (resp) {
        $scope.Attractions = resp.data;
    });
}

This way the controller will wait for the ng-init directive.

Sign up to request clarification or add additional context in comments.

1 Comment

Exactly what I've got, thanks for pointing me in the right direction! Something so simple.. completely overthought that!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.