These are chat archives for angular/angular.js

1st
Nov 2016
Anders Borum
@andersborum
Nov 01 2016 11:41
hi there, anyone experienced with the ngComponentRouter?
i'm trying to figure out, how to keep descending routes from activating if a top level component e.g. discovers that the user is not authenticated
if i navigate on a top level, it seems like the descending target route/component still receives the activation event
and i'd like a generalized solution such that components don't need to repeat this logic
any takers?
Anders Borum
@andersborum
Nov 01 2016 11:47
so i have e.g. a hierarchy of nested routes: A/B/C, A/B/D, A/B/E (like 3 different terminating routes under B)
if the user somehow gets unauthenticated (clears cookies etc.) and reloads the browser, I'd like to navigate to the sign-in route
Frederik Prijck
@frederikprijck
Nov 01 2016 11:48
@andersborum Angular 2 right ?
Anders Borum
@andersborum
Nov 01 2016 11:48
nopes, it's 1.5.8 with ngComponentRouter
so right now i've implemented $routerOnActivate() on the "A" controller, which gets called nicely but when I issue a call to this.$rootRouter.navigate(), the descending routes keep initializing (cascading)
so the question is, how do i keep the routing infrastructure from continuing to initialize descending routes (in this case, the B/[C, D, E] routes? I'd rather not litter the error checking in each descending $routerOnActivate impl.
i'm 100% positive, that the this.$rootRouter.navigate() is invoked, and it works unless a descending route/component throws an error (which is likely to occur because the auth is expired)
pointers? tips?
Nicholai Nissen
@Nicholaiii
Nov 01 2016 12:16
@andersborum We are using ui-router and we call a function on every state-change that looks similar to this: http://hastebin.com/oboxugakub.cs
Anders Borum
@andersborum
Nov 01 2016 13:26
@Nicholaiii i just found a pretty nice workaround; in the top controller I implemented $canActivate() on the component and injected the required dependencies. If the criteria aren't met, I navigate to login from that point and return false from the function. This way, descending routes don't get initialized. Works like a charm, actually.
class InjectorService {
    static getInstance(): angular.auto.IInjectorService {
        return angular.element(document.body).injector();
    }
}

// on the component itself
$canActivate: () => {
    var container = InjectorService.getInstance();
    var stateServices = container.get<IStateServices>(ServiceConstants.StateServices);
    var $rootRouter = container.get<angular.Router>("$rootRouter");

    if (!stateServices.auth.getState()) {
        $rootRouter.navigate([
            RouteConstants.Users.Name,
            RouteConstants.Users.SignIn.Name]);
        return false;
    }

    if (!stateServices.organization.getState()) {
        $rootRouter.navigate([
            RouteConstants.Users.Name,
            RouteConstants.Users.ChooseOrganization.Name]);
        return false;
    }

    return true;
}
it's a typescript spa we're building
perhaps the above snippet can be of use to you as well
at least it relieves all descending components from having the responsibility of calling a static helper or something similar
lots of ceremony to get rid of
Danny Fenstermaker
@dfenstermaker
Nov 01 2016 17:04
Anyone know of a way to resolve a promise/async value in the $get of a provider and use that as to create the actual return service object?
Matt Erman
@CodeLiftSleep
Nov 01 2016 17:27
                  this.Get = function (route, errorMsg) {
                        return Restangular.one(route).get()
                            .then(null, function (e) {
                                alertify.error(errorMsg); //Message passed in when it errors
                                console.log('Error!! ' + e.name + ':  ' + e.message); //console logs name of error and message
                                return $q.reject(e);
                            });
                    };
@dfenstermaker just sub in $http.get for Restangular and it should work
thats a service its running in
Danny Fenstermaker
@dfenstermaker
Nov 01 2016 17:29
@CodeLiftSleep thats not resolving the $get though right? I am not sure why restangular would be needed for to resolve the $get of a provider. It simply returns a promise from that code to which the $get would need to kow how to resolve before creating the actual service itself
Rudolf Schöneberg
@rudirus
Nov 01 2016 17:29
app.service('dataSource', ['$http', DataSource]);

function DataSource($http) {   
        this.data = function() {
            $http.get('https://someapi.io/merchant/info')
            .success(function(response) {
                return "inside_promise";
            });
            return "outside_promise";
        }
}

app.controller('MainController', ['$scope', 'dataSource', function MainController($scope, dataSource) {
  $scope.data = dataSource.data();
}]);
Can someone tell me how to provide the data of a service which makes requests to an external API correctly?
I just want to make one API request inside the service, store the result in a service variable and make it available to all controllers which depend on the service, but somehow I'm continuously failing and only getting the flat "outside_promise" response.
Matt Erman
@CodeLiftSleep
Nov 01 2016 17:30
@rudirus you shouldn't use .success and .error its deprecated...you should be using .then and .catch
@rudirus look at what I just posted above
Rudolf Schöneberg
@rudirus
Nov 01 2016 17:30
@CodeLiftSleep thanks, noted and won't be used in future
Matt Erman
@CodeLiftSleep
Nov 01 2016 17:30
That this.Get is coming from APIService
so then the call is APICalls.Get(Route, ErrorMsg).then(function(response) { $scope.data = response});
in the controller
you need to change the function to this.DataSource
@dfenstermaker Restangular is pretty awesome...it provides it's own promises and it gets resolved on the .then call in the controller in my example
@dfenstermaker in your case you would do something like this:
Frederik Prijck
@frederikprijck
Nov 01 2016 17:34
@rudirus U need:
app.service('dataSource', ['$http', DataSource]);

function DataSource($http) {   
        this.data = function() {
            return $http.get('https://someapi.io/merchant/info')
            .then(function(response) {
                return response; // here you can return properties of response eg: response.data
            });
        }
}

app.controller('MainController', ['$scope', 'dataSource', function MainController($scope, dataSource) {
  dataSource.data().then(function(response){
     $scope.data = response;
  });
}]);
When doing async calls with promises, data is not returned but passed as a callback to the then method.
You can't simply do $scope.data = dataSource.data() as thats not the actual data but the Promise representing the actual data.
So to retrieve the data you do:
dataSource.data().then(function(response){
     $scope.data = response;
  });
Rudolf Schöneberg
@rudirus
Nov 01 2016 17:36
@frederikprijck @CodeLiftSleep thanks for the help, I really appreciate it
Danny Fenstermaker
@dfenstermaker
Nov 01 2016 17:36
@CodeLiftSleep I think we are talking about different things :) that said I used Restangular for quite a while and found it was very performance heavy, that may have been cleaned up but at the time was not worth the composition functionality it provides
thanks!
Matt Erman
@CodeLiftSleep
Nov 01 2016 17:37
@dfenstermaker Seems pretty good to me, we use it on a large web portal at work, not sure how long ago you were using it
It was a little bit of a pain in the butt to get it to do what I wanted but once I did the code reduction was pretty phenomenal
Danny Fenstermaker
@dfenstermaker
Nov 01 2016 17:40
@CodeLiftSleep I liked it but found out that everytime you compose a function onto a restangular object it creates a new object and does some other things which I considered unnecessary, but glad it is working for your team :)
Matt Erman
@CodeLiftSleep
Nov 01 2016 17:42
Truth be told I had all the CRUD calls working with $http from a service as well where I called one line in the main Controller too, but they wanted to go with Restangular for some built in functionality down the road so I was like OK I can refactor it
this.Get = function (model, route, successMsg, errorMsg) {
-                        var deferred = $q.defer();
-                        $http
-                            .get(route)
-                            .then(function (response) {
-                                model = response.data;
-                                //alertify.success(successMsg); //Message passed in when its successful
-                                deferred.resolve();
-                            }, function (e) {
-                                alertify.error(errorMsg); //Message passed in when it errors
-                                console.log('Error!! ' + e.name + ':  ' + e.message);
-                                deferred.reject();
-                            });
-                        return deferred.promise;
-                    };
@dfenstermaker try that
that is in a service but you can modify it for your needs
Danny Fenstermaker
@dfenstermaker
Nov 01 2016 17:47
I am very confused by that code
your creating a promise then resolving the promise inside anther promise
why not just return the result of $http?
Matt Erman
@CodeLiftSleep
Nov 01 2016 17:49
It might not be necessary, but it worked...you probably could do that, I'm still learning JS I'm a C# programmer
Frederik Prijck
@frederikprijck
Nov 01 2016 17:49
You want this:
this.Get = function (route, successMsg, errorMsg) {
                       return $http
                           .get(route)
                           .then(function (response) {
                               return response.data;
                           }, function (e) {
                               alertify.error(errorMsg); //I wouldn't handle this here
                               console.log('Error!! ' + e.name + ':  ' + e.message);
                               return e;
                           });
                  };
Matt Erman
@CodeLiftSleep
Nov 01 2016 17:49
Listen to @frederikprijck lol
Frederik Prijck
@frederikprijck
Nov 01 2016 17:50
I ment for your sample @CodeLiftSleep , I removed the parts @dfenstermaker was talking about
Matt Erman
@CodeLiftSleep
Nov 01 2016 17:50
Thanks, that was old code that isn't being used anymore, we have it going through restangular now
Frederik Prijck
@frederikprijck
Nov 01 2016 17:50
Oh okay
Matt Erman
@CodeLiftSleep
Nov 01 2016 17:51
      //GET Function
                    this.Get = function (route, errorMsg) {
                        return Restangular.one(route).get()
                            .then(null, function (e) {
                                alertify.error(errorMsg); //Message passed in when it errors
                                console.log('Error!! ' + e.name + ':  ' + e.message); //console logs name of error and message
                                return $q.reject(e);
                            });
                    };
Frederik Prijck
@frederikprijck
Nov 01 2016 17:51
Ok :-D
Matt Erman
@CodeLiftSleep
Nov 01 2016 17:51
is what we have currently
Frederik Prijck
@frederikprijck
Nov 01 2016 17:51
Ye you're not creating ur own promise, that's better
λ • Geovani de Souza
@geovanisouza92
Nov 01 2016 18:44
Hello guys, I would like to ask: there is anyone here managing multiple (related) ng projects on a monorepo?
Danny Fenstermaker
@dfenstermaker
Nov 01 2016 20:25
@geovanisouza92 I manage a single repo that builds to electron and web, but thats about it