Search code examples
javascriptangularjsnode.jsasynchronouscytoscape

JavaScript access to Angular scope returning "undefined" - Asynchronous issue?


Problem: I'm trying to get some data from a server to populate a cytoscape graph. When i access the scope from javascript its undefined.

Despite their being quite a few posts with this / similar issue. I'm having trouble finding an explanation about how to get round the problem of accessing the scope from a javascript file, once the data is ready (if that is the problem im having).

I read that http.get methods are asynchronous? so they don't block anything after from executing. I guess this is what is causing an undefined error when i'm accessing the scope because the data hasn't returned yet? I've found some info on this but can't figure out what to use to get round the problem. I can access the data in the usual way in HTML with the angular curly braces and it works. It also works when i just return some data from the controller.

If anyone can point me in the right direction i'd really appreciate it.

This is javascript file im trying to run which grabs the scope and adds nodes to a cytoscape graph.

<script type="text/javascript">
    window.onload = function() {
        nodes = angular.element(document.querySelector('[ng-controller="DataController"]')).scope().nodes;
        alert(nodes);
        cy.add(nodes);
    }
</script>

2. which calls a factory method from the controller.

dataFactory.getNodes().then(function(data)
    {
        $scope.nodes = data;
    });

3. http.get from the factory

_service.getNodes = function()
    {
        return $http.get(urlBase + "/nodes");
    };

4. node.js returns some 'nodes' to add to the cytoscape graph

router.get('/api/data/nodes', function(req, res) {
        console.log('sending some data');
        var data = [
            ...
            ];
        res.status(200).json(data);
    });

I've seen "promises" mentioned so i guess i'll be heading in that direction next...

Thanks


Solution

  • You are trying to alert the value of nodes when the DOM is loaded (window.onload) and the data from the service is not yet returned. Your controller is already uses a promise, and the data is binded to the scope when the promise is resolved.

    .then(function(data){
        ...
    });
    

    If you specifically want to access the data from an external js script, you can simply call the function from the controller:

    script

    <script type="text/javascript">
    function alertNodes() {
        nodes = angular.element(document.querySelector('[ng-controller="DataController"]')).scope().nodes;
        alert(nodes);
        cy.add(nodes);
    }
    </script>
    

    controller

    dataFactory.getNodes().then(function(data){
            //$scope.nodes = data;
            alertNodes()
        });