8

I want to initialize a Angular model with a JSON object which is embedded in a HTML page. Example:

<html>
  <body>
    <script type="text/javascript" charset="utf-8">
      var tags = [{"name": "some json"}];
    </script>
    <ul>
      <li ng-repeat="tag in tags">{{tag.name}}</li>
    </ul>
  </body>
</html>

The tags field cannot be resolved, because it is looked up in the $scope. I tried to access the tags field in my controller like this:

function TagList($scope, $rootScope) {
  $scope.tags = $rootScope.tags;
}

But it doesn't work.

It works only if I include the TagList directly into the HTML page and render the JSON directly into this function.

How can I access the tags field in a separate js file in a Angular controller?

1 Answer 1

11

There are at least two ways:

  1. Declare your tags array in a standalone script tags, in which case your tags variable will be bound to window object. Inject $window into your controller to access your window-bound variables.
  2. Declare your tags array inside the ng-init directive.

Showing both solutions:

HTML:

<body>

  <script type="text/javascript" charset="utf-8">
    var tags = [{"name": "some json"}];
  </script>

  <div ng-controller="AppController">
    tags: {{tags | json}}
    <ul>
      <li ng-repeat="tag in tags">{{tag.name}}</li>
    </ul>
  </div>  

  <div>
    <ul ng-init="tags = [{name: 'some json'}]">
      <li ng-repeat="tag in tags">{{tag.name}}</li>
    </ul>
  </div>

</body>

JS:

app.controller('AppController',
  [
    '$scope',
    '$window',
    function($scope, $window) {
      $scope.tags = $window.tags;
    }
  ]
);

Plnkr

I strongly advise against polluting window object.

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

4 Comments

Is there any other way to initialise a variable in the view without having to declare it inside a HTML tag? For example, if the tags array declared inside ng-init above was a really large array and I want to initialise it in the view (from server side code for ex.) can I use something like {{ tags = [{...}] }} instead?
@Stewie there are also issues with the second approach. If the tags are generated through a jsonify method, and if they contain quotes, everything will brake
I can't see any better way than using $window for @GFoley83's use case; I have the same problem, I send down an initial JSON payload with the markup that I want to inject into the controller, but this is surprisingly difficult to do with Angular. I don't like polluting the window object either (or having to pull in globals either), but it seems like the best way.
@ElYobo Yeah it is surprisingly difficult, with no clean way of solving it yet. I'm thinking I'd prefer to use something like <input type="hidden" data-ng-init="tags = [{name: 'some json'}]" /> instead of having to pass around global variables.

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.