2015-10-13 1 views
0

У меня есть фабрика, которая проверяет authData пользователя, используя firebase. Я хочу получить доступ к данным пользователей, таким как имя, адрес электронной почты и т. Д., Но я не могу понять, как получить данные моментального снимка в объекте, который я могу использовать. Я новичок в Javascript.Как вернуть данные пользователя из Factory в контроллер с использованием Firebase

это моя фабрика:

angular.module('.....') 
    .factory('UserDataService', function($q, $firebase, $firebaseAuth, FIREBASE_URL) { 
    var authData = {}; 

    function authDataCallback(authData) { 
     if (authData) { 
     var ref = new Firebase(FIREBASE_URL + "/userProfiles/" + authData.uid); 
     ref.on("value", function(snapshot) { 
      var data = snapshot.val(); 
     }); 

     } else { 
     console.log("User is logged out"); 
     } 
    } 

    // Register the callback to be fired every time auth state changes 
    var ref = new Firebase(FIREBASE_URL); 
    ref.onAuth(authDataCallback); 

    return authData; 
}); 

второго Покушение:

На этот раз я могу получить пользователь подробность, но это не спасет в переменную службу и возвращается к контроллеру как null. Вот мой код:

var firebaseRef = new Firebase(FIREBASE_URL); 
    var authObj = $firebaseAuth(firebaseRef); 
    activate(); 
    var service = { 
     userInfo: null 
    }; 


    function activate() { 
     // Add listeners for authentication state changes 
     authObj.$onAuth(function(authData) { 
      if (authData) { 
       // Load the userInfo 
       loadUserInfo(authData); 
      } else { 
       // Destroy the userInfo Object if one exists 
       if (service.userInfo) { 
        service.userInfo.$destroy(); 
        service.userInfo = null; 
       } 
      } 
     }); 
    } 

    function loadUserInfo(authData) { 
     var userRef = firebaseRef.child('userProfiles').child(authData.uid); 
     var loadedInfo = $firebaseObject(userRef); 
     // console.log(loadedInfo); 

     loadedInfo.$loaded() 
     .then(function() { 
      service.userInfo = loadedInfo; 
      console.log(service.userInfo.name); 
     }) 
     .catch(function(error) { 
      switch (error.code) { 
       case 'PERMISSION_DENIED': 
        alert('You don\'t have the permission to see that data.'); 
        break; 
       default: 
        alert('Couldn\'t load the user info.'); 
      } 
     }); 
    } 
    return service; 
+0

Это немного неясно (по крайней мере для меня), что вы пытаетесь достичь. Можете ли вы попытаться описать свое желаемое поведение/результат немного больше? – LionC

+0

Я пытаюсь получить доступ к объекту «authdata» с контроллера, который содержит имя пользователя и т. Д. ... Я хочу передать моментальный снимок в объект authdata – nareeboy

ответ

0

Предполагая, что моментальный снимок верен, метод val() превращает его в объект. Значение данных теперь содержит нужные значения. Например, data.name.

Служба должна выставить функцию для этого

function sendData() { 
    var deferred = $q.defer(); 
    // Register the callback to be fired every time auth state changes 
    var ref = new Firebase(FIREBASE_URL); 
    ref.onAuth(function(snapshot) { 
    deferred.resolve(snapshot.val()); 
    }); 

    return deferred.promise; 
} 

Что-то вроде этого

Приветствиях

+0

Да, это так. Но мне нужно получить доступ к этим данным в контроллере: например, $ scope.objectname.name. Как передать снимок во что-то, к чему я могу получить доступ? – nareeboy

+0

Прежде всего, я думаю, что первая попытка ближе к рабочему, который у меня есть. Я понимаю эту проблему. Решение состоит в том, чтобы выставить функцию в службе, которая возвращает обещание. В этой функции подписаться на onAuth, и когда это произойдет, разрешите обещание. – user1820709

+0

Проблема заключается в том, что контроллер будет запускаться перед фабрикой, и объект вернется как null – nareeboy

1

Вы должны вводить свой сервис внутри что-то (контроллер, обслуживание, фильтр или директивы) и от контроллер, вызовите служебную функцию.

.controller('myController', ['UserDataService', function($scope) { 
    $scope.userService = UserDataService; 
} 

Теперь вы можете вызвать функцию из области вашего контроллера.

userService.authDataCallback() 
1

Вы назначаете snapshot.val() к локальной переменной data. data уничтожается, как только функция заканчивается.

Вам необходимо присвоить его «внешней» переменной authData, которой вы не можете, поскольку у вас есть параметр функции с тем же именем.

Попробуйте так:

angular.module('.....') 
    .factory('UserDataService', function($q, $firebase, $firebaseAuth, FIREBASE_URL) { 
    var authData = {}; 

    function authDataCallback(data) { 
     if (data) { 
     var ref = new Firebase(FIREBASE_URL + "/userProfiles/" + data.uid); 
     ref.on("value", function(snapshot) { 
      authData = snapshot.val(); 
      //[see comment] var authData = snapshot.val(); 
     }); 

     } else { 
     console.log("User is logged out"); 
     } 
    } 

    // Register the callback to be fired every time auth state changes 
    var ref = new Firebase(FIREBASE_URL); 
    ref.onAuth(authDataCallback); 

    return { 
     authData: authData 
    }; 
}); 

Также вы должны прочитать о типах возвращения сервиса/фабрики в документации. То, что возвращает объект фабрики, в основном предоставляет частные переменные/функции для доступа к другим модулям.

+0

, все еще возвращая пустой объект. – nareeboy

+0

в моем контроллере я сделал это: var userService = UserDataService; console.log (userService.authData); и он сказал undefeined – nareeboy

+0

aw, дерьмо. Это 'var authData = snapshot.val();' в моем ответе. Удалите 'var'! - Отредактировал мой ответ. Кроме того, если это не работает, проверьте, работает ли его доступ, когда вы устанавливаете 'authData = {test: 'test'};' – j2L4e

0

Я полагаю, что есть в var data a объект. Вы можете легко получить доступ к полям с точкой .field. Например:

ref.once("value", function(snapshot) { 
    var data = snapshot.val(); 
    // data is { "name": "Fred", "age": 53 } 
    // data.name === "Fred" 
    // data.age === 53 
}); 

В зависимости от данных в DataSnapshot, метод Val() может возвращать примитивный (строка, число или логическое значение), массив или объект. Он может также возвращать null, указывая, что моментальный снимок пуст и содержит данных нет.

Взято из: https://www.firebase.com/docs/web/api/datasnapshot/val.html

Я надеюсь, что это помогает.

-EDIT- Используйте этот формат, чтобы получить данные в контроллере:

var app = angular.module("sampleApp", ["firebase"]); 

app.factory("Auth", ["$firebaseAuth", 
    function($firebaseAuth) { 
    var ref = new Firebase("https://docs-sandbox.firebaseio.com", "example3"); 
    return $firebaseAuth(ref); 
    } 
]); 

app.controller("SampleCtrl", ["$scope", "Auth", 
    function($scope, Auth) { 
    $scope.auth = Auth; 

    // any time auth status updates, add the user data to scope 
    $scope.auth.$onAuth(function(authData) { 
     $scope.authData = authData; 
    }); 
    } 
]); 
+0

И чтобы вернуть его, вы должны создать пустой пустой объект, как @ j2L4e, и назначить новое значение внутри обратного вызова. Затем верните его. –

+0

Как передать переменную данных в объект, доступ к которому я могу получить с контроллера? – nareeboy

+0

Я ** думаю ** проблема в том, что ваш обратный вызов является асинхронным, и поэтому вы получаете пустой объект. Попробуйте использовать ваш сервис с помощью. Then ... использование обещаний может решить проблему, но вам нужно переписать все. https://docs.angularjs.org/api/ng/service/$q –