0

Ok, first of all, clearify that I am veeery new on AngularJS. I tried to search for something helpful on other answers but could not find anything to solve my problem.

So hear it is. I am starting a "test project" to improve my angular skills. So far I am able to get a JSON from a Rest Service. My next step is getting it but loading the URL from a config file. I am doing it on a very easy way, just getting the config file from my local server as it is a JSON file stored there.

Of course I know that the problem is understanding the lifecycle of variables. But after reading some documentation, nothing new...

This is my controller:

app.controller('LoginController', [
    '$scope',
    'props', //this gets the properties file (json)
    'HttpResourceProvider', //this gets any json from a rest service
    function($scope, props, httpResourceProvider) {
        var myData;
        props.success(function(data) {
            console.log("1: "+myData); //undefined
            serverVersion = myData;
            console.log("2: "+myData); //defined
        });
        console.log("3: "+myData); //undefined
        httpResourceProvider.call(
                "http://localhost:8080/.../2.5", //instead of 2.5, 
                //here should go the constant myData.version
                function(data) {
                    $scope.serverVersion = data;
                });
        console.log($scope.serverVersion); //undefined?
        $scope.date = new Date();

        $scope.login = function() {
            console.log("hey" + $scope.user + " " + $scope.password);
        };
    } ]);

The problem comes on the "props" factory, I dont know how to modify the global variable "myData" because of course the "myData" variable into the function is just a different variable.

Actually I put another console.log after the other factory method "httpResourceProvider" to see the result of $scope.serverVersion and same problem! And here I am quite impressed because of course I can use this variable on the view...

So any suggestions of how to modify my code so it works? Or any useful documentation to learn more on this topic? Any help is welcome.

Thanks a lot!

2
  • 1
    You'd better use app.constant, like app.constant('myConst', 'blah');. then you just inject this constant in the controller by adding myConst to dependencies Commented Jan 20, 2016 at 14:34
  • Well, for one thing, you are never assigning any value to myData. What is the props service? Can you include the code for that? Just from looking at the code you posted, it looks like you need to assign myData = data in the callback handler for props.success. If that information is required by call to httpResourceProvider, then you need to wait until the first callback is called to execute the second call. Commented Jan 20, 2016 at 14:41

2 Answers 2

1

The problem is that you do several asynchronous calls but you treat them like synchronous calls, the order of something asynchronous would be something like this:

  1. httpResourceProvider.call - async
  2. console.log($scope.serverVersion); //undefined?
  3. httpResourceProvider done, resolve
  4. Execute resolve function: function(data) { $scope.serverVersion = data; });

So your next line of code which relies on some of the async data is already executing before the data is loaded, and therefore is undefined.

For more info about promises and how to properly chain them I recommend you to read this article.

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

1 Comment

Exactly. Just after posting I was searching for more information and found something about synchronous calls. Now with your answer, everything is clearer! Now I get that everything called on the "success" method, will be synchronous, so I am doing all the stuff there. Thanks!!
0

As @k102 mentioned, this sort of thing is most properly done by injecting the information at configuration time. The configuration part of the lifecycle precedes bootstrapping, so if it requires an asynchronous call to retrieve the information, you will have to use deferred bootstrapping.

Another, simpler option is to create a JavaScript file that includes only the AngularJS call to create the serverVersion constant value. For example that file could contain just this code:

angular.module("MyApp").value("serverVersion", "2.5");

Note that "MyApp" is whatever you called your module.

Then include that file along with your other script files and inject the constant into your module like so:

app.controller('LoginController', [
    '$scope',
    'serverVersion', // injects the server version value
    'props',
    'HttpResourceProvider',
    function($scope, serverVersion, props, httpResourceProvider) {
        // serverVersion === '2.5'

Comments

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.