1

i used a tutorial to create a angularfire chat app. it is a standalone app that uses ui-router. I integrated it succssfully as a view in my app but that is not practical. I need to be able to use the chat on any view I am at. I am stuck at moving a resolve function to a controller. I have read some docs and I believe it is returning a promise that I need to resolve in the controller. the link to the tutorial is here. tutorial

here is the ui-router I am trying to get away from

.state('channels.direct', {
                 url: '/{uid}/messages/direct',
                 templateUrl: 'views/chat/_message.html',
                 controller: 'MessageController',
                 controllerAs: 'messageCtrl',
                 resolve: {
                     messages: function ($stateParams, MessageService, profile) {
                         return MessageService.forUsers($stateParams.uid, profile.$id).$loaded();
                     },
                     channelName: function ($stateParams, UserService) {
                         return UserService.all.$loaded().then(function () {
                             return '@' + UserService.getDisplayName($stateParams.uid);
                         });
                     }
                 }
             })

The message service

  var channelMessagesRef = new Firebase(AppConstant.FirebaseUrl + 'channelMessages');
    var userMessagesRef = new Firebase(AppConstant.FirebaseUrl + 'userMessages')

    return {
        forChannel: function (channelId) {
            return $firebaseArray(channelMessagesRef.child(channelId));
        },
        forUsers: function (uid1, uid2) {
            var path = uid1 < uid2 ? uid1 + '/' + uid2 : uid2 + '/' + uid1;

            return $firebaseArray(userMessagesRef.child(path));
        }
    };

the user service

 var usersRef = new Firebase(AppConstant.FirebaseUrl + 'users');
    var connectedRef = new Firebase(AppConstant.FirebaseUrl + '.info/connected');
    var users = $firebaseArray(usersRef);
    return {
        setOnline: function (uid) {
            var connected = $firebaseObject(connectedRef);
            var online = $firebaseArray(usersRef.child(uid + '/online'));

            connected.$watch(function () {
                if (connected.$value === true) {
                    online.$add(true).then(function (connectedRef) {
                        connectedRef.onDisconnect().remove();
                    });
                }
            });
        },
        getGravatar: function (uid) {
            return '//www.gravatar.com/avatar/' + users.$getRecord(uid).emailHash;
        },
        getProfile: function (uid) {
            return $firebaseObject(usersRef.child(uid));
        },
        getDisplayName: function (uid) {
            return users.$getRecord(uid).displayName;
        },
        all: users
    };

here is what I have so far in the controller

 $scope.directMessage = function (uid) {
        UserService.all.$loaded().then(function () {
            $scope.selectedChatUser = '@' + UserService.getDisplayName(uid);
        });
        $scope.selectedChatUserMessages = MessageService.forUsers(uid, profile.$id).$loaded();
    };

I am returning the

$scope.selectedChatUser

fine. the issue is with the Message Service

this is the what i am currently returning from the message service

$$state: Object
__proto__: Promise

how do i resolve this?

1 Answer 1

2

You're trying to return from inside a promise in your channelName function.

The object you're getting back is an unresolved promise. You want the resolved data from the promise injected into your controller.

You need to create a to return from this function.

.state('channels.direct', {
   url: '/{uid}/messages/direct',
   templateUrl: 'views/chat/_message.html',
   controller: 'MessageController',
   controllerAs: 'messageCtrl',
   resolve: {
      messages: function ($stateParams, MessageService, profile) {
        return MessageService.forUsers($stateParams.uid, profile.$id).$loaded();
      },
      channelName: function ($stateParams, UserService, $q) {
         // create a deferred for this function
         var deferred = $q.defer();
         // load async data with UserService.all's promise
         UserService.all.$loaded()
           .then(function () {
              var name = UserService.getDisplayName($stateParams.uid);
              deferred.resolve(name);  
           });
         // return promise
         return deferred.promise;
      }
   }
})

However in getDisplayName I would just recommend returning back the object rather than just the name, as the entire set is synchronized by Firebase.

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

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.