Firebase - Angular - Multiple clauses - angularjs

I need something like that, but i dont get the correct concatenation with the for and the push. In fact, i would like to avoid doing multiple queries, one per "palabras[i]". It would be excelent if i be able to go only one time to the database:
function ($scope, $rootScope, $stateParams, $firebaseArray) {
var arrayRta = new Array();
var palabras = $rootScope.textAreaOfrecer.toLowerCase().split(' ');
for (i = 0; i < palabras.length; i++) {
var elementosConI = firebase.database().ref().child("solCompras").orderByChild("palabras/" + palabras[i]).equalTo(true);
arrayRta.push(elementosConI);
}
$scope.solicitudes = arrayRta;//$firebaseArray(arrayRta);
}
{
"solCompras" : {
"-KdTUecpbUuWJO_Fbj5Y" : {
"palabras" : {
"123" : true,
"444" : true,
"123123" : true
},
"post" : "123 123123 444",
"user" : "demo"
},
"-KdTcRy_P0rjEpnHwHCC" : {
"palabras" : {
"123" : true
},
"post" : "123",
"user" : "demo"
},

If you're looking to add the words to the list in the database, just call firebase.database().ref().child("solCompras").push(palabras[i]) for each word.
This is going to be as fast as adding them all in one call, because the requests are pipelined over the same connection. See Speed up fetching posts for my social network app by using query instead of observing a single event repeatedly

Related

select2 multiple ajax calls

I'm trying to call 2 REST APIs and then populate the select2 dropdown.
My select2 code works fine for 1 API call but doesn't if I try to call the 2 API in AJAX results.
The way I'm trying to call the second API looks a but dicey to me but I'm not too sure how do I achieve this. I can nest AJAX calls if not using them in select2 but this is a bit peculiar case.
Any idea on how to achieve that/ or what am I doing wrong here
below is the code for that:
Select2({
disabled : true,
minimumInputLength : 1,
multiple : true,
ajax : {
url : "/rest/api/2/user/picker" ,
type : "GET",
dataType : 'json',
cache : true,
// query parameters for the remote ajax call
data : function data(term) {
return {
query : term,
maxResults : 5,
showAvatar : true
};
},
// parse data from the server into form select2 expects
results : function results(data) {
var i, dataLength, dataUsers;
data = JSON.parse(data);
var users = [];
dataLength = data.users.length;
dataUsers = data.users;
for (var i = 0; i < dataLength; i++)
{
if (dataUsers[i].key != $scope.userInputs.owner.key) {
dataUsers[i].context = CommonConstants.RECIPIENT_AUTH_CONTEXT.USER;
users.push(dataUsers[i]);
}
}
if($scope.someBoolean){
ajax : {
url : "/rest/api/2/groups/picker",
type : "GET",
dataType : 'json',
cache : true,
data : function data(term) {
return {
query : term,
maxResults : 5
};
},
success: function(responseForGroups){
var groupData = JSON.parse(responseForGroups);
var dataGroups, groupsLength;
dataGroups = groupData.groups;
groupsLength = groupData.total;
for (var i = 0; i < groupLength; i++)
{
dataGroups[i].context = CommonConstants.RECIPIENT_AUTH_CONTEXT.GROUP;
dataGroups[i].key = dataGroups[i].name;
dataGroups[i].displayName = dataGroups[i].name;
users.push(dataGroups[i]);
}
}
};
}
return {
results : users
};

How can search JSON for a value key and return the nested data?

The below block is my JSON. The -KTYLrHDHt234rFDNHrm type hashes are generated by the supplied API of the client. I think they're using Firebase.
I am passing a query in the URL which contains the pageId for each of those nested objects.
Example https://cms.app.io/edit/Nike3243
But since the hash is auto generated how can I search through all the JSON and check if the pageId matches my Angular route and then only return the values of the same child.
{
"-KTYLrHDHtdq23423NHrm": {
"pageCreation": "10/8/2016, 14:14:22 PM",
"pageGallery": {
"slider_1_img": "http://",
"slider_2_img": "http://",
},
"pageId": "Nike13243",
"pageName": "Nike Campaign 1",
"store": "11"
},
"-KTYLrHDHtdqirFDNHrm": {
"pageCreation": "10/8/2016, 12:14:22 AM",
"pageGallery": {
"slider_1_img": "http://",
"slider_2_img": "http://",
},
"pageId": "Nike323243",
"pageName": "Nike Campaign 2",
"store": "12"
},
"-KTYLrHDHt234rFDNHrm": {
"pageCreation": "10/8/2016, 13:14:22 PM",
"pageGallery": {
"slider_1_img": "http://",
"slider_2_img": "http://",
},
"pageId": "Nike3243",
"pageName": "Nike Campaign 3",
"store": "13"
}
}
So I want to return only the data of Nike3243 but I want to return the store, the slider and the pageName. How can I do this since the KTYLrHDHt234rFDNHrm hash is something I will never know
cmsApp.controller('pages-edit', function ($scope, $http, $routeParams) {
var pageIdU = $routeParams.id;
$http.get(firebase_url+'cms/home.json'+randstatus).success(function(data) {
$scope.pages = data;
// this would be pageId = Nike3243
console.log(data.pageIdURI.pageName[pageId]);
});
});
Thanks
Assuming your object is called 'objTest', you could do something like this:
var strPageId = 'The page id to find', objFound;
for( var strKey in objTest ) {
var objTemp = objTest[strKey];
if ( objTemp['pageId'] == strPageId ) {
objFound = objTemp;
break;
}
}
if ( typeof objFound == "object" ) {
//Do something...object has been found!
}
I actually did this:
$.each(data, function (bb) {
var crossReference = data[bb].transId;
if (crossReference==pageIdUri) {
$scope.transNameEn = data[bb].transNameEn;
$scope.transNameArabic = data[bb].transNameArabic;
$scope.transCreation = data[bb].transCreation;
$scope.transModified = data[bb].transModified;
$scope.notes = data[bb].notes;
}
});
It may be easier for you to simply transform the data rather than perform this search over and over. You can loop through the data once and get it in the correct format.
I would do something like:
var recordLookup = {};
for (var id in records) {
var pageId = records[id].pageId;
recordLookup[pageId] = record[id];
recordLookup[pageId].originalId = id;
}
This way you can now easily look up any record by its page id. If you need to send the data back to the server in the original form you still have that original id and can do whatever you need to in order to get it in the proper format. This way you loop once or maybe twice, (once to make the lookup and once to revert at the end of your operation) rather than any time you need to get data out of your records.

How to set total records dynamically from the controller

Here is the problem,
Server responds with several records in JSON, which number is greater than grid pageSize parameter specified in the Store. The total number is not returning by a server in this JSON with data. The number of such records is known and could be different (this number should be requested from the server in another request). The total number is needed for the pagingtoolbar.
How to tell the proxy reader this number from the view controller?
The only workable solution I found is to override the Ext.data.reader.Json reader with the following code:
Ext.define('MyApp.custom.AnotherReader',{
extend: 'Ext.data.reader.Json',
alias : 'reader.anotherReader',
// разбираем ответ и записываем в store
getResponseData : function(response) {
var st = Ext.decode(response.responseText);
st.total = 5;
//console.log(st);
return st;
}
});
The problem is I cannot dynamically change this total parameter from the viewcontroller.
JSON 1:
[
{
"id":"1",
"user_id":"11",
},
{
"id":"2",
"user_id":"12",
},
{
"id":"3",
"user_id":"13",
},
{
"id":"4",
"user_id":"14",
},
{
"id":"5",
"user_id":"15",
}
]
JSON 2:
{
"records_count": "5"
}
You can do this inside your controller -
// some event handler/ or normal function inside your Controller that you'll call
somFunction: function() {
var me = this;
var store = Ext.getStore(<storeId>); // you can even pass the store
//instance as a parameter to this function
var reader = store.getProxy().getReader();
Ext.override(reader, {
getResponseData : function(response) {
var st = Ext.decode(response.responseText);
st.total = me.getValueYouWant();
return st;
}
});
}

Pick random record from Firebase with AngularFire

Is there any way to get random record from firebase like this:
{
"-JbmopNnshefBT2nS2S7" : {
"dislike" : 0,
"like" : 0,
"post" : "First post."
},
"-JbmoudijnJjDBSXNQ8_" : {
"dislike" : 0,
"like" : 0,
"post" : "Second post."
}
}
I used this code to solve the problem, but it download all records, so if DB would be bigger, my app will work very slow:
HTML code:
<div ng-controller="RandomCtrl">{{RandomPost.post}}</div>
JS code:
var app=angular.module('App', ['firebase']);
app.controller('RandomCtrl', function($scope, $firebase){
var ref = new Firebase("https://ind.firebaseio.com/");
var sync=$firebase(ref);
$scope.messages = sync.$asArray();
$scope.GetRandomPost=function(){
return $scope.RandomPost=$scope.messages[Math.floor(Math.random()*$scope.messages.length)];
};
$scope.GetRandomPost();
});
You can use startAt with your own incremental index. For example, suppose you have index (0 to n) in your records.
Do this query: orderByChild("index").startAt(rint).limitToFirst(1);
See the code snippit:
var rint = Math.floor((Math.random() * 10)) // you have 10 records
var query = ref.orderByChild("index").startAt(rint).limitToFirst(1);
var results = $firebaseArray(query);
results.$loaded(
function(x) {
// let's get one
$scope.oneResult = x[0];
}, function(error) {
console.error("Error:", error);
});
};
You can work with an object that contains all keys to solve the issue with large DBs, regarding picking up a random key I think you are good the way you are doing it.
Another way to do I guess is using incremental keys as #lombausch said, then you can use a combination of key() method to get the last key added and then get a random based on the min, max values.
Here is the anti-pattern to save incremental/numeric keys:
https://www.firebase.com/docs/web/guide/saving-data.html#section-push
key() method reference:
https://www.firebase.com/docs/web/api/firebase/key.html

Firebase.util - similar intersections with completely different results

I'm working on an angular project that uses Firebase as it's sole backend, angularFire for some synchronisation cases and I'm using this tool Firebase.util for dealing with shared resources. My case is this:
{
users {
user1 : {
tasks : {
active : {
task1 : true,
task2 : true
},
archived : {
task3 : true,
task4 : true
}
},
...
},
tasks : {
task1 : {
users : {
user1 : true,
user2 : true
}
},
...
}
},
}
and I'm dealing with the query like this:
var tasksRef = new $window.Firebase(FIREBASE_URL + '/tasks');
function _userActiveTasksRef(userId) {
return new $window.Firebase(FIREBASE_URL + '/users/' + userId + '/tasks/active');
}
function _userArchivedTasksRef(userId) {
return new $window.Firebase(FIREBASE_URL + '/users/' + userId + '/tasks/archived');
}
function getActive(userId) {
var interRef = $window.Firebase.util.intersection(_userActiveTasksRef(userId), tasksRef);
return $firebase(interRef).$asArray();
}
function getArchived(userId) {
var interRef = $window.Firebase.util.intersection(_userArchivedTasksRef(userId), tasksRef);
return $firebase(interRef).$asArray();
}
On the first case, when I intersect the active tasks with the "all tasks" ref everything works fine but when I try to perform the same operation with the archived tasks the intersection is always empty. I've already logged the individual queries and everything is working as expected, only the intersection doesn't seem to work. Is there any caveat that I'm missing? The two queries are being loaded at the same time if that matters.. the result is being stored in a controller like this:
this.tasks = {
active: tasks.getActive(currentUser.uid),
archived: tasks.getArchived(currentUser.uid)
};

Resources