Accessing data from a $firebaseobject based on data from another $firebaseobject - angularjs

I have the following structure on Firebase.
+Groups
-group1
-groupMessage: abc
-groupName: xyz
-members
-User1 = STATUS: "true"
-User2 = STATUS: "pending"
+group2
+group3
etc..
+Users
-User1
-Groups
-group1 = STATUS: "true"
-group3 = STATUS: "pending"
etc..
+User2
+User3
etc..
I'm trying to display group info to individual users based on whether they have a "true" or "pending" status. My app has separate page views for "pending" and "true" statuses.
Below is how I'm trying to achieve this.
.controller('GroupCtrl', function($scope, $firebaseObject, $rootScope) {
// Get a reference to the Firebase account
var fbRef = new Firebase("https://####.firebaseio.com/");
// Get a reference to where the User's Group IDs are stored
var fbUserCircle = new Firebase(fbRef + "/Users/" + $rootScope.fbAuthData.uid + "/Groups/");
var fbCircles = new Firebase(fbRef + "/Groups/");
var obj = $firebaseObject(fbUserCircle.orderByChild("Status").equalTo("pending"));
obj.$loaded().then(function() {
console.log("loaded record:", obj.$id);
// Iterating the key/value pairs of the object
angular.forEach(obj, function(value, key) {
var groupObj = $firebaseObject(fbCircles.child(key));
console.log("$ref: " + circlesObj.$ref());
circlesObj.$loaded().then(function() {
circlesObj.$bindTo($scope, "groups");
})
})
})
})
In my page view I'm trying to display {{groups.groupName}} and {{groups.groupMessage}} over ng-repeat for a user who has groups with a "pending" status.
No data is being displayed in my view for displaying a user's group with "pending" statuses. What am I doing wrong? Anyone one know of a better way of doing this?

Related

How do you save two values in a user field using angularjs?

I've got a requirement where I need to assign a SharePoint task to two users. Code below assigns it to one user but not the second when creating a task.
first user value _spPageContextInfo.userId second user value taskcase.Caseownername,
$scope.createTask = function() {
var item = $scope.taskDetails;
var taskcase = $scope.caseDetails;
var updates = angular.extend({}, {
Title: item.Title,
DueDate: item.DueDate ? moment(item.DueDate, 'DD/MM/YYYY').format() : null,
Status: item.Status,
AssignedTo: _spPageContextInfo.userId && taskcase.Caseownername,
RelatedCase: $routeParams.id
});
ModalDialog.showWaitScreen({
message: 'Creating task for case ' + updates.Title
}).then(function (waitScreen) {
return CaseManagementService.createTask({
updates: updates
}).then(function (task) {
$log.info('task created', task);
$scope.taskDetails = {
Status: 'Not Started'
};
$scope.loadRelatedTasks();
return ModalDialog.delayClose(waitScreen, 200);
}, function(e){
console.error(e);
});
});
};
You need get the userid from the taskcase.Caseownername object, and then pass the data like below.
AssignedToId: {'results':[_spPageContextInfo.userId,user2Id]}
Refer to: How to update Person field with multiple values using REST API
_spPageContextInfo.userId sounds like an integer value and taskcase.Caseownername sounds like a string value
Is AssignedTo a string? Then just do:
AssignedTo: _spPageContextInfo.userId + taskcase.Caseownername,
This will save both values as 1 string
Is it an integer? You can't save two values in 1 property...

realtime firebase database get property name and value on child_changed

I am working on real-time fire-base database.
i have a issue in getting value what is changed in fire-base.
i have client social database inside it posts and then kkkm(this is key) and then different properties and values and what i want is to toggle approval and rejected values like that approval:true but what i get is just true/false not the property name.
toggleCheck = (id) => {
var ref = firebase.database().ref('posts/'+id);
ref.off("child_changed");
var approval;
ref.on("child_changed", function (data) {
approval = data.val();
console.log("=============================");
console.log("The updated approval is " + approval);
});
}
toggleClose = (id) => {
var ref = firebase.database().ref('posts/'+id);
ref.off("child_changed");
var rejected;
ref.on("child_changed", function (data) {
rejected = data.val();
console.log(ref.getKey());
console.log(ref.getValue());
console.log("=============================");
console.log("The updated rejected is " + rejected);
});
}
I'm not 100% sure to understand what you want to do ("toggle approval and rejected values"?) but, based on the code in your question, the following is probably what you are looking for:
var ref = firebase.database().ref('posts/' + id);
ref.on('child_changed', function(data) {
console.log(data.key); // <-- Name of the field/node that was modified
console.log(data.val()); // <-- Value of the field/node that was modified
console.log("The updated" + data.key + " is " + data.val());
});
Explanations:
data is a DataSnapshot which has:
A key property, which is "the key (last part of the path) of the location of this DataSnapshot."
A val() method, which "extracts a JavaScript value from a DataSnapshot."
UPDATE FOLLOWING YOUR COMMENTS
I understand that you want to get both the values of the approval and rejected nodes (fields) when something changes in the post.
Therefore you should use the value event type instead of the child_changed one, as follows:
var ref = firebase.database().ref('posts/' + id);
ref.on('value', function(data) {
var approved = data.val().approved;
var rejected = data.val().rejected;
var object = {'approved': approved, 'rejected': rejected};
//Do whatever you want with the object
console.log(object);
});

angularjs reinitializing arrays gives me "TypeError: Cannot read property 'push' of undefined"

I am running into a peculiar problem.
I have a my view of drop down list as this in HTML:
<div ng-controller='ConfigurableInputController as configurableInput'>
<select class="fixed-input"
ng-model="configurableInput.selectedCriteria"
ng-change="configurableInput.update()"
ng-options="criterion.selected as criterion.name for criterion in configurableInput.criteriaList">
<option value="">--Please select the comparison criteria--</option>
</select>
The above shows me 3 options in drop down list: Store, Channel and Permissions.
When ever I change the option from Store to Channel or Permissions or any combination the view changes (input boxes, certain labels etc.)
My update() method in controller does this:
configurableInput.update = function () {
configurableInput.permission = "";
configurableInput.id1 = "";
configurableInput.id2 = "";
configurableInput.items1 = "";
configurableInput.items2 = "";
configurableInput.defaultValueArray = [];
configurableInput.permissionsArr = [];
}
On selection of the drop down item, I do a ng-click on a button which retrieves information from Db.
There are 2 flavors of methods which are called on ng-click but the one giving me trouble is this one in the Service method:
StoreConfigurableService.$inject = ['$q', '$http', 'ApiBasePath'];
function ConfigurableService($q, $http, ApiBasePath) {
var service = this;
var defaultValueArr = [];
var permissionsArr = [];
var items1 = "";
var items2 = "";
service.retrievePermissions = function (criterion, id1, id2, rlNumber1, rlNumber2) {
$q.all([
$http.get(ApiBasePath + "/" + criterion + "/" + id1 + "/" + rlNumber1),
$http.get(ApiBasePath + "/" + criterion + "/" + id2 + "/" + rlNumber2)
])
.then(function (response) {
items1 = response[0].data;
items2 = response[1].data;
if (criterion === 'Permissions') {
var processed = false;
permissionsArr = makePermissionsArray(permissionsArr, items1, items2, processed);
}
})
.catch(function (errorResponse) {
console.log("Error: " + errorResponse);
throw errorResponse;
});
};
... so on
In my makePermissionsArray() I am doing this:
function makePermissionsArray(arr, items1, items2, processed) {
var map = items1.storePermissions;
var map2 = items2.storePermissions;
var map3 = items1.allPermissions;
for (var key in map) {
arr.push({
'code': key,
'description': map3[key],
'repStorePermission1': map[key],
'repStorePermission2': map2[key]
});
}
}
I get this permissionsArr back to controller through this:
service.getPermissionsArr = function () {
return permissionsArr;
};
NOTE that 'arr' in the argument of method makePermissionsArray() is not initialized because I am getting it by passing permissionsArr in the argument.
Now how the flow goes is:
First I select Store from drop down list, click on button to retrieves configurables for the store. This gives me correct response.
Then I select 'Permissions' from drop down list, click on button to retrieve permission configurables from Db, it gets stuck and does not get me any response.
I thought I am not clearing the arrays correctly in update() method and after some long search I found and changed these array initializing from:
configurableInput.defaultValueArray = [];
configurableInput.permissionsArr = [];
to
configurableInput.defaultValueArray.length = 0;
configurableInput.permissionsArr.length = 0;
in my update() method.
Now what happens is this:
First I select Store from drop down list, click on button to retrieves configurables for the store. This gives me correct response.
Then I select 'Permissions' from drop down list, click on button to retrieves permission configurables from Db, it gives me correct response.
I select Store from drop down list again, click on button and I get correct response.
But when I again select 'Permissions' from drop down list, click on button, it gives me this error - TypeError: Cannot read property 'push' of undefined
Error I get is at this point:
arr.push({
'code': key,
'description': map3[key],
'repStorePermission1': map[key],
'repStorePermission2': map2[key]
});
I am literally tearing my hair out because of this problem. Can someone please help me what's wrong?

Comparing items in $firebaseArray to object and removing matching items

I feel like I'm so close, but I can't figure this out.
I have a data tree in Firebase with events and under each event is a list of participants with their user id and name.
-events
-UniqueID
-participants
-userID
facebook_id: "12345678"
display_name: "John Doe"
-userID
facebook_id: "12345678"
display_name: "John Doe"
-userID
facebook_id: "12345678"
display_name: "John Doe"
In my routes I have a resolve function that queries the Facebook API for users who have my app installed and passes a friends object into the controller.
This is a page for the user to invite friends to the event. I want to check the participants array and remove users who are already in the event from the friends object.
I loop through the $firebaseArray and use lodash to find the corresponding id. Lodash's _.find returns the object if found or undefined if not found.
I found this removeItemsById function in another answer here, but it doesn't seem to work.
The _.find works correctly because I see it log the matched item, but it doesn't get removed from the object. Any ideas?
$scope.participants = $firebaseArray(firebase.database().ref().child("events").child($stateParams.eventID).child("participants"));
$scope.participants.$loaded().then(function(){
console.log(friends);
angular.forEach($scope.participants, function(part){
var i = _.toString(part.facebook_id);
console.log(part.facebook_id);
var f = _.find(friends, {'id': i});
console.log("f value is: " + f);
if (f) {
console.log("Found matching facebook id: " + part.facebook_id);
removeItemsById(friends, part.facebook_id);
}
})
$scope.friends = friends;
})
function removeItemsById(arr, id) {
var i = arr.length;
if (i) { // (not 0)
while (--i) {
var cur = arr[i];
if (cur.id == id) {
arr.splice(i, 1);
}
}
}
}

using query to read the last value and change it firebase angularjs 1

I have this database
service/
-KSxobYDhjUJeSvu3dC1
-Accion:"Nueva ronda"
-Codigo: 3
-dateTime: 1475284727
-notify: 0
-num_mesa: 0
-KSxobptdYSc-qrCSbyU
-Accion: "Orden cancelada"
-dateTime: 1475284728
-notify: 0
-num_mesa: 0
and then I have this code:
ref.orderByChild("notify").equalTo(1).limitToLast(1).on("child_added", function(snapshot) {
var changedPost = snapshot.val();
var mykey = snapshot.key;
if(changedPost.notify == 1 ){
var message = "New action "
console.log(serviceArray[mykey].notify);//undefined
$scope.showActionToast(message);
}
});
This code will read the last entry in the database and show a toast, notifying that a new action has been inserted in firebase. It shows the toast.
My problem is that I don't want it to show every time i reload the page.
So I thought about adding a simple flag that if it was shown in a toast, it will change notify to 0.
My problem is that I have service that returns a firebaseArray named serviceArray. When I try to access the row to change the value it says undefined. How can I change the value in the same function?
You're going to be better off simply tracking the timestamp of the last message you've shown to the user. With that you can query for messages that were added after that timestamp:
var timestampOfMostRecentlySeenMessage = null;
if (timestampOfMostRecentlySeenMessage) {
ref.orderByChild("timestamp")
.startAt(timestampOfMostRecentlySeenMessage)
.limitToLast(1)
.on("child_added", function(snapshot) {
var message = snapshot.val();
timestampOfMostRecentlySeenMessage = message.dateTime;
})
Now you just need to maintain the value of timestampOfMostRecentlySeenMessage between page reloads. You could do this in a cookie, in local storage of your browser or even in a user-specific part of your database:
var userRef = firebase.database().ref("users").child(user.uid);
userRef.child("timestampOfMostRecentlySeenMessage").set(timestampOfMostRecentlySeenMessage);
i just added a flag that declares after running the search for the first time.
ref.orderByChild("notify").equalTo(1).limitToLast(1).on("child_added", function(snapshot) {
var changedPost = snapshot.val();
var mykey = snapshot.key;
if(changedPost.notify == 1 && $scope.flag== 1 ){
var message = "New action "
console.log(serviceArray[mykey].notify);//undefined
$scope.showActionToast(message);
}
$scope.flag= 1;
});

Resources