Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sharing data from asynchronous calls amongst directives in AngularJS with TypeScript

I can find bits and pieces of how to solve this, but no concrete way to make it work.

I have an asynchronous call to a server to fetch data in AngularJS and wish to store it in a variable. This variable then needs to be accessible to all the directives in the app, but they obviously all need to wait for the variable to be assigned before they can use it. I'm also using TypeScript and its export functionality to spin directives from their own functions.

Controller

export class MainController{
   fundData: Object;

   constructor(scope, FundService) {

       FundService.fetchData('some_param').then(d => {
           let data = d[0],
               fundProps = data.properties_pub;

           this.fundData = {
               'isin': data.clientCode,
               'nav': fundProps.nav.value,
               'nav_change': fundProps.nav_change.value.toFixed(2),
               'nav_change_direction': change,
               'total_aum': fundProps.net_asset.value.toFixed(2)
           };

           scope.ctrl = this;
       });  
   }
}

Directive

class OverviewController {
    scope: ng.IScope;

    constructor(scope){

        scope.$watch('data', newVal => {
            console.log(newVal);
        });
    }
}

OverviewController.$inject = ['$scope'];

export function overview(): ng.IDirective {
    return {        
        restrict : "C",
        controller : OverviewController,
        controllerAs : "overview",
        template : require("../templates/overview"),
        bindToController :{
            data: '='
        }
    }
}

HTML

<div ng-controller="MainController">
    <div class="overview" data="ctrl.fundData"></div>
</div>

Bootstrap Process

let module = angular.module(MODULE_NAME,[])
                .controller('MainController', ['$scope','FundService', MainController])
                .service('FundService', FundService)
                .directive('overview', overview);

Things I've Tried:

$rootScope

I can set something static and share it, so this works:

$rootScope.data = 2;

This doesn't:

someFunction().then(data => { $rootScope.data = data });

Maybe there's something about promises in $rootScope I don't understand.

Setting in controller

I can set the result of the call to a variable in the controller, set that to an attribute in the directive, and then bind the attribute to its controller, but this doesn't work either, even if I use $watch on the variable.

like image 855
BHouwens Avatar asked Dec 01 '25 23:12

BHouwens


1 Answers

What I would do is fetch the data, store it in a service (which I think you are already doing) and then broadcast an event when the data in the service is updated. Here's an example (in raw javascript)

module.service('DataService', function(rootScope) {
    ...
    var data;
    services.setData = function(newData) {
        data = newData;
        rootScope.$broadcast('DataUpdated');
    };
    ...
});

And then in your directives all you would need to do is listen for the 'DataUpdated' event:

scope.$on('DataUpdated', ...);

Hope that helps!

like image 170
Robin Avatar answered Dec 03 '25 14:12

Robin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!