1

I'm aware of how to do this with a promise on an http request, but in this case, the data must be initialized from an inline script.

This controller is already defined in the header js:

var testModule = angular.module('myTestModule', []);
testModule.controller('testCtrl', function ($scope) {
    $scope.data = [];
});

The following html loads, and for sake of argument, let's say it takes a very long time to finish the script part:

<div ng-app="myTestModule" ng-controller="testCtrl">
...
</div>
<script type="text/javascript">
    setInitialData(['boo', 'far']);
</script>

If the inline script were loaded BEFORE the div with ng-app, I wouldn't be having an issue, but in this case it may load after the controller has been instantiated. I'm trying to avoid an extra http request, though it's convenient to utilize a promise with an angular service.

Does anyone have any ideas for how to construct the function setInitialData so that it applies the data to the controller/scope?

4
  • The "right" way, as you mention, is to make an AJAX request as you've already mentioned Commented Jul 29, 2014 at 2:55
  • It just seems wasteful to make two requests when the data is available to the application while fulfilling the first request. Commented Jul 29, 2014 at 2:59
  • I realize the question is about how to get the inline script to work, but why? Have you considered calling setInitializedData from inside your controller or your app's run block? Commented Jul 29, 2014 at 3:08
  • It has to do with custom framework restrictions. Javascript is put into a separate content block beyond the main body. Commented Jul 29, 2014 at 3:16

1 Answer 1

1

You can use the angular.element(...).scope() method to get a reference to the scope for any DOM element (protip: use angular.element($0).scope() in the devtools JS console to get the scope for the currently selected element in the Elements tab).

From there you can make changes to the scope as required. Make sure to call $apply() to make AngularJS aware of the change.

e.g.

<div ng-app="myTestModule" ng-controller="testCtrl" id="testCtrl">
...
</div>
<script type="text/javascript">
    function setScopeValue(selector, scopeProp, value) {
        angular.element(selector).scope().$apply(function ($scope) {
            $scope[scopeProp] = value;
        });
    }

    function setInitialData(data) {
        setScopeValue('#testCtrl', 'data', data);
    }

    setInitialData(['boo', 'far']);
</script>

Note that my setScopeValue() function only works for a single level of property access, so dots are not supported. If you needed to set nested properties, you would want to use $parse() to create a setter function you can call with the $scope and the value to set.

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

1 Comment

Thanks for the quick help. There is one caveat; jqLite won't work with the '#testCtrl' selector. I ended up using angular.element(document.getElementById(id))

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.