Firebase return multiple objects - firebase

I am using firebase and in below query extand() is a function that concatenate the objects. Can some one help me to remove $timeout from my query ?
currently i am waiting for my playerList to fill.
var getJoinedPlayers = function(gameId){
var deferred = $q.defer();
var playerList = {};
var usersRef = new Firebase(FBURL+'users');
var gameRef = new Firebase(self.firebaseURL);
var gamePlayersRef = gameRef.child(gameId).child("players");
gamePlayersRef.on("child_added", function(snap) {
usersRef.child(snap.key()).once("value", function(data) {
playerList[snap.key()] = extend({'playerId': snap.key()},data.val());
})
});
$timeout(function() {
if (playerList) {
deferred.resolve(playerList);
} else {
reason = {'message': "player Not found"};
deferred.reject(reason);
}
}, 1300);
return deferred.promise;
};

I would simplify this by replacing "child_added" with "value". This will return the list of players, which you could iterate over with regular JS.
Then call
usersRef.child(snap.key()).once("value", function(data)
for each of of the items in the result, and push each of these promises into an array
promiseArray.push(usersRef.child(snap.key()).once("value", function(data)...
then you could
$q.all(promiseArray).then(...
that will combine all promises into a single promise

Related

Firebase Request Timeout Feature [duplicate]

I'm trying to create a cloud function for firebase that remove a user depending on the delay value and insert back the after the number of delay.
exports.delayqueue = functions.database.ref('/queues/{queueid}/members/{memberid}').onWrite(event => {
var members = event.data.ref.parent;
var user = event.data;
var queueid = members.parent;
var userid = event.params.memberid;
var delayfor = user.child('delay').val();
var name = user.child('name').val();
if(delayfor != 0){
members.child(event.params.memberid).remove();
join(userid,queueid,delayfor,name);
return;
}else{
return;
}
});
function join(userid,queueid,delayfor,name){
setTimeout(function(){
var ref = db.ref("queues/queueid/members/userid");
ref.set({
name: name,
timestamp: Date.now(),
delay : 0
});
}, delayfor*1000);
};
But it's not working can someone help?
You'll need to wrap your setTimeout in a Promise:
exports.delayqueue = functions.database.ref('/queues/{queueid}/members/{memberid}').onWrite(event => {
var members = event.data.ref.parent;
var user = event.data;
var queueid = members.parent;
var userid = event.params.memberid;
var delayfor = user.child('delay').val();
var name = user.child('name').val();
if (delayfor !== 0){
members.child(event.params.memberid).remove();
return join(userid,queueid,delayfor,name);
} else {
return;
}
});
function join(userid,queueid,delayfor,name){
return new Promise((resolve, reject) => {
setTimeout(function(){
var ref = db.ref("queues/queueid/members/userid");
ref.set({
name: name,
timestamp: Date.now(),
delay : 0
}).then(resolve, reject);
}, delayfor*1000);
});
};
Note that the time spent waiting for setTimeout is billed as function execution time and is also subject to the function timeout. If you're only delaying a few seconds, that might be okay, but if the delay is expected to be minutes this solution isn't going to be viable or cost-effective.

Sharing data stored in angularjs

I'm trying to shared data between controller.
I'm calling data, then stored in AngularJS Factory variable.
My goal when stored the data was to make it accessible to any controller. But in application, every time i called the stored data from each controller, seems like i got a new instance of my factory instead of my factory that already contain the data.
Do you think i'm doing the wrong way when using factory or there was something i've been missed ?
Here it is
Factory Code:
var Credentials = ['abc'];
function load() {
var service = HeaderService.get("api/CredentialsAPI/get");
service.then(function (response) {
if (response.status == 200)
Credentials = response.data;
});
alert("inside:" + Credentials.length);
}
load();
return {
SubmitCredentials : function (obj) {
angular.forEach(obj, function (value) {
Credentials.push(value);
});
},
GetCredentials : function (name) {
var datax = {};
alert(Credentials.length)
angular.forEach(Credentials, function (value) {
if (value.Name == name) {
datax = value;
}
});
return datax;
}
}
Home Controller:
loadHome();
function loadHome() {
$scope.Credentials = CredentialsService.GetCredentials("Task");
}
AssignTask
$scope.showSubmitView = false;
//----------------------------------function--------------------------------------
$scope.Credentials[] = CredentialsService.GetCredentials("Task");
You're referencing a new array every time. That's why you're getting new data. You should be referencing the service instead, and have the service take care of the push() and get for you.
Factories and Services are singletons... Meaning they're only instantiated once. The pattern to share data is below:
Factory
app.factory('CredentialService',["$http", function($http) {
var credentials = [];
var submitCredentials = function(obj) {
angular.forEach(obj, function(value) {
credentials.push(value);
});
}
var getCredentials = function(name) {
var datax = {};
if(credentials.length === 0)
return datax;
angular.forEach(credentials, function(value) {
if(value.Name === name) {
datax = value;
break; //i think you meant to break; over here
}
});
return datax;
}
//return the service;
return {
getCredentials: getCredentials,
submitCredentials: submitCredentials
};
}]);
Controller
app.controller("Ctrl1", ["$scope", "CredentialService", function($scope, CredentialService) {
var credObj = CredentialService.getCredentials('blahblahblah');
var someNewCredObj = 'blahhhh';
CredentialService.submitCredentials(someNewCredObj);
}]);

Can't load dictionary using knockout mapping plugin

I found the solution how to use the observable array as dictionary on http://jsfiddle.net/karlhorky/D4D3f/
ko.observableArray.fn.indexBy = function (keyName) {
var index = ko.computed(function () {
var list = this() || [];
var keys = {};
ko.utils.arrayForEach(list, function (v) {
if (keyName) {
keys[v[keyName]] = v;
} else {
keys[v] = v;
}
});
return keys;
}, this);
this.findByKey = function(key) {
return index()[key];
};
return this;
};
I'd like to load data to dictionary using mapping plugin
this.Load = function () {
//this.items.
var mapping = {
'copy': ["Qid"]
};
ko.mapping.fromJS(data, mapping, this.items);
count = 0;
};
but can't search by key data loaded using mapping plugin
demo: http://jsfiddle.net/RqSDv/
The mapping plugin turns regular properties into observable properties.
So in your indexBy you need to handle the case when your keyName refers to a ko.observable.
When you get the key property value with v[keyName] you need to use ko.utils.unwrapObservable (or ko.unwrap if you using a newer version of KO) to make sure to correctly unwrap your observable property:
ko.observableArray.fn.indexBy = function (keyName) {
var index = ko.computed(function () {
var list = this() || [];
var keys = {};
ko.utils.arrayForEach(list, function (v) {
if (keyName) {
keys[ko.utils.unwrapObservable(v[keyName])] = v;
} else {
keys[v] = v;
}
});
return keys;
}, this);
this.findByKey = function (key) {
return index()[key];
};
return this;
};
Demo JSFiddle.

Firebase on() does not return anything

I have this piece of code using on() to get data from Firebase, inside on() I create object which I want to send out of function for future use - using return, but it seems it doesn't return anything.
So question is how can I make it right?
postsRef.on('value', function(snapshot) {
if (snapshot.val() === null) {
var allPosts = false,
numberOfPosts = 0;
}
else {
var allPosts = snapshot.val(),
numberOfPosts = Object.size(allPosts);
}
var postsData = {
content: allPosts,
count: numberOfPosts
};
return postsData;
});
The callback function is called asynchronously (some time in the future). So by the time it is invoked, postsRef.on(...) has already returned and any code immediately after it will have run.
For example, this might be tempting, but would not work:
var postsData;
postsRef.on('value', function(snapshot) {
postsData = snapshot.val();
});
console.log(postsData); // postsData hasn't been set yet!
So there are a few different ways to tackle this. The best answer will depend on preference and code structure:
Move the logic accessing postsData into the callback
postsRef.on('value', function(snapshot) {
postsData = snapshot.val();
console.log(postsData);
});
Call another function when the callback is invoked
function logResults(postsData) {
console.log(postsData);
}
postsRef.on('value', function(snapshot) {
logResults(snapshot.val());
});
Trigger an event
function Observable() {
this.listeners = [];
}
Observable.prototype = {
monitorValue: function( postsRef ) {
var self = this;
postsRef.on('value', function(snapshot) {
self._notifyListeners(postsRef);
});
},
listen: function( callback ) {
this.listeners.push(callback);
},
_notifyListeners: function(data) {
this.listeners.forEach(function(cb) {
cb(data);
}
}
};
function logEvent( data ) {
console.log(data);
}
var observable = new Observable();
observable.listen( logEvent );
observable.monitorValue( /* postsRef goes here */ );

Setting $scope.items in Angular Binding

I have a service with the following function,
public object Get(AllUsers request)
{
var users = XYZ.GetAllUsers();
var userList = users.Cast<XYZ>();
return new AllUsers
{
UsersAcc = userList.Select(ConvertToEntity).ToList()
};
}
I am trying to get the results from angular controller.
function UserAccountController($scope, $location, $filter, UserAccount) {
#scope.items = function(){
var abc = UserAccount.query();
return abc.UsersAcc
}
}
Here is my Service
angular.module('userAccService', ['ngResource']).factory('UserAcc', function($resource) {
return $resource('/api/useracc/:id', {}, {
query: {
method: 'GET',
}
});
I am new to angular service, and can't seem to make it to work.
You need to create an array object and return it. After the query is done you can populate that same instance with the list UsersAcc. Keep in mind that $scope.items will be [] untill the query returns with data.
$scope.items = getUsersAcc();
function getUsersAcc() {
var dataArray = new Array();
UserAccount.query(function (data) {
var list = data.UsersAcc;
for (var i = 0, c = list.length; i < c; i++) {
dataArray.push(list[i]);
}
};
return dataArray;
};

Resources