This is probably a noob question but I am following this firebase util
scroll ref pagination to retrieve my data from firebase database. I want to receive only those objects that meet the criteria of user city but its not working as I am not receiving anything in return.
The code I am trying is
var baseRef = new Firebase("https://myfirebaseurl.firebaseio.com");
var norm = new Firebase.util.NormalizedCollection(
baseRef.child('Events') // the master index
);
// filter the client-side results to only include records where event_city matches user city
norm = norm.filter(function(data, key, priority) {
return data.event_city === $rootScope.userCity; // setting $rootScope.userCity initially
});
// specify the fields for each path
norm = norm.select( 'Events.lat', 'Events.lng', 'Events.event_city', 'Events.event_state' );
var ref = norm.ref();
var scrollRef = new Firebase.util.Scroll(ref,"event_city");
$rootScope.events= $firebaseArray(scrollRef);
// load the first ten events
scrollRef.scroll.next(10);
`
My Firebase structure is really simple
root :
Events :{
-Event1-id :{
created_on: 225325223,
event_state: "abc",
event_city:"äbc",
event_desc:"abd",
lat : 28.1234567, //event latitude
lng : 77.1234567, //event longitude
event_address : "abc",
event_date : 446343643
},
-Event2-id:{
.....
},
-Event3-id:{
}....
}
Please help me out. Sorry this is my first question here so let me know if anything else is required.
Related
I am using some Graph view to view some statistic in my project.
e.g. Morish Grapgh, Pie chart graph.
I have an option like date range, so that I can specify the range of date and can fetch the data within that range and show the output graph in the front end.
The issue I am facing is at the First time I am able to see the out put while I am changing the Date range.
from the second time I am able to get the Data from the backend but after setting the new set of values to the graph Data, but the graph view is not changing because the graph is not able to refresh.
Here sample code. Please ask if any additional info needed.
<sa-morris-graph *ngIf="graphData!=null" [data]="graphData"
type="area"
[options]="{
xkey: 'x',
ykeys: ['y', 'z'],
labels: ['USER', 'New USER']
}"></sa-morris-graph>
from the Component type script file I am setting graphData
export class GAUserComponent implements OnInit{
fromDate : any ;
toDate : any ;
graphData : any = null;
dateSelected(){
this.gaService.getGaData(this.req,"/users")
.subscribe(
data => {
this.dataResponse = data;
let grData = [];
for (let data of this.dataResponse.usersByDate) {
var sample={"x": data.valueX ,"y": data.valueY , "z" : data.valueZ };
grData.push(sample);
}
this.graphData = grData;
},
err => {
console.log("Error occered : "+ err);
}
);
}
Please suggest me to solve the problem.
I guess In angular 1 there is a watch() to achieve this but in angular 2 this function is not there.
correct me If I am wrong and help me solve this
Thanks
I'm using angular-ui-fullcalendar to show and edit events. Users can log in and have unique uid when logged in. I want to use this to distinguish events made by current user from other events. I want to give current user events another backgroundColor.
What is the best way to do this??
I tried several things. My data looks like this:
```
database
bookings
-KWnAYjnYEAeErpvGg0-
end: "2016-11-16T12:00:00"
start: "2016-11-16T10:00:00"
stick: true
title: "Brugernavn Her"
uid: "1f17fc37-2a28-4c24-8526-3882f59849e9"
```
I tried to filter all data with current user uid like this
var ref = firebase.database().ref().child("bookings");
var query = ref.orderByChild("uid").equalTo(currentAuth.uid);
var bookings = $firebaseArray(query);
$scope.eventSources = [bookings];
This doesn't return anything. If I omit the filter in line 2 it returns all bookings as expected. But even if the filter worked it would not solve my problem, because I want to fetch both current user events and all other events. Firebase does not have a "not equal to" filter option...
I tried to loop through each record and compare uids and setting backgroundColor if condition was met:
var ref = firebase.database().ref().child("bookings");
var bookings = $firebaseArray(ref);
bookings.$ref().on("value", function(snapshot) {
var list = snapshot.val();
for (var obj in list) {
if ( !list.hasOwnProperty(obj) ) continue;
var b = list[obj];
if (b.uid === currentAuth.uid) {
b.className = "myBooking";
b.backgroundColor = "red";
}
}
});
$scope.eventSources = [bookings];
But this causes asynchronous problems so the 'bookings' array assigned to $scope.eventSources wasn't modified. I tried to move the $scope.eventSources = [bookings] inside the async code block but FullCalendar apparently can't handle that and renders nothing.
I also tried this but no luck either:
bookings.$loaded()
.then(function(data) {
$scope.eventSources = [data];
})
.catch(function(error) {
console.log("Error:", error);
});
What is the best solution to my problem?
If you're looking to modify the data that is loaded/synchronized from Firebase, you should extend the $firebaseArray service. Doing this through $loaded() is wrong, since that will only trigger for initial data.
See the AngularFire documentation on Extending $firebaseArray and Kato's answer on Joining data between paths based on id using AngularFire for examples.
My goal is to write a SAPUI5 Fiori app with routing support. One mail goal is to have passable URLs. For example in an E-Mail like "please approve this: link". The link is an URL matched by my rounting config, e.g.index.html#/applicants/8.
I use a typical sap.m.SplitApp kind of application. Clicking a list item in masterview changes the URL to index.html#/applicants/[id of entry in JSON]. I can click on the list, my defined routes are getting matched and the apps loads the (applicant) data as expected.
However, and here comes my question, this doeas not work when using an URL directly, say pasting [my url]/index.html#/applicants/8 into my browser. The app is launched but no detail data is loaded. I have to click on another list item again to get the data.
Actually, the controller is called when passing the URL, but it seems the model is not initiated and undefined. My JSON model is bound in the createContent function of my Component.js
// Update 2015-05-14
The problems seems to be around the getData() function. I have the model, it has the entries, but getData() returns undefined for the first time my app is loaded. I recently read getData() is deprecated. How should I improve my coding below?
// Component.js
ui5testing.Component.prototype.createContent = function(){
// create root view
var oView = sap.ui.view({
id : "app",
viewName : "ui5testing.view.Main",
type : "JS",
viewData : {
component : this
}
var oModel = new sap.ui.model.json.JSONModel("model/mock_applicants.json");
oView.setModel(oModel);
[...]
return oView;
});
// Master controller
handleApplicantSelect : function (evt) {
var oHashChanger = sap.ui.core.routing.HashChanger.getInstance();
var context = evt.getParameter("listItem").getBindingContext();
var path = context.getPath();
var model = this.getView().getModel();
var item = model.getProperty(path);
oHashChanger.setHash("applicants/" + item.id);
},
// Detail controller
onInit: function() {
this.router = sap.ui.core.UIComponent.getRouterFor(this);
this.router.attachRoutePatternMatched(this._handleRouteMatched, this);
},
_handleRouteMatched : function(evt){
var objectId = evt.getParameter("arguments").id;
var model = this.getView().getModel();
var data = model.getData()["applicants"];
var pathId;
if (data) {
for (var i = 0; data.length; i++) {
if ( objectId == data[i].id ) {
pathId = i;
break;
}
}
var sPath = "/applicants/" + pathId;
var context = new sap.ui.model.Context(model, sPath)
this.getView().setBindingContext(context);
}
},
As you've figured out that getData() returns undefined for the first time, which means the model data is still not yet loaded. So you can make use of attachRequestCompleted method of the model & fire an event from the component & listen to that event in the detail controller to ensure the routerPatternMatched() gets executed only after the data is loaded.
//Component.js
var oModel = new sap.ui.model.json.JSONModel("model/mock_applicants.json");
oModel.attachRequestCompleted(jQuery.proxy(function(){
this.fireEvent("MockDataLoaded"); // fireEvent through component
},this));
oView.setModel(oModel);
//Detail controller
onInit : function(){
this.router = sap.ui.core.UIComponent.getRouterFor(this);
var oComponent = this.getOwnerComponent();
oComponent.attachEvent("MockDataLoaded",jQuery.proxy(function(){
this.router.attachRoutePatternMatched(this._handleRouteMatched, this);
},this));
}
Or the simplest & but the dirty way would be to make an synchronous request instead of an async request to load data.
var oModel = new sap.ui.model.json.JSONModel();
oModel.loadData(""model/mock_applicants.json",{bAsync:false});
oView.setModel(oModel);
The Patterns and Practices team has released a client side taxonomy picker for use when integrating with SharePoint. It works well, but uses jQuery and my SharePoint App is built in Angular... which seems to be a growing trend. I would like to leverage the client side taxonomy picker in Angular and was unsure of how best to achieve this. Here is a link to the component: https://github.com/OfficeDev/PnP/tree/dev/Components/Core.TaxonomyPicker
I am thinking it would be a directive, or is there a non-directive manner to replace (aka, how does Angular manage a replace/initialization) as they are doing here:
HTML:
<input type="hidden" id="taxPickerGeography" />
jQuery Function that gets the Current Context and creates the Taxonomy Picker
$(document).ready(function () {
var context;
context = SP.ClientContext.get_current();
$('#taxPickerGeography').taxpicker({
isMulti: false,
allowFillIn: false,
termSetId: '89206cf2-bfe9-4613-9575-2ff5444d1999'
}, context);
});
I don't need the script loading components as illustrated in the example provided by the PnP team, as I have these already embedded in my App.
Given the challenges of making a "responsive" Managed Metadata field, I built the following using the JavaScript Object Model to retrieve terms and then push them for use in an Array. This includes retrieving Synonyms.
// Query Term Store and get terms for use in Managed Metadata picker stored in an array named "termsArray".
var termsArray = [];
function execOperation() {
// Current Context
var context = SP.ClientContext.get_current();
// Current Taxonomy Session
var taxSession = SP.Taxonomy.TaxonomySession.getTaxonomySession(context);
// Term Stores
var termStores = taxSession.get_termStores();
// Name of the Term Store from which to get the Terms. Note, that if you receive the following error "Specified argument was out of the range of valid values. Parameter name: index", you may need to check the term store name under Term Store Management to ensure it was not changed by Microsoft
var termStore = termStores.getByName("TermStoreName");
// GUID of Term Set from which to get the Terms
var termSet = termStore.getTermSet("TermSetGUIDHere");
var terms = termSet.getAllTerms();
context.load(terms);
context.executeQueryAsync(function () {
var termEnumerator = terms.getEnumerator();
while (termEnumerator.moveNext()) {
var currentTerm = termEnumerator.get_current();
var guid = currentTerm.get_id();
var guidString = guid.toString();
var termLabel = currentTerm.get_name();
// Get labels (synonyms) for each term and push values to array
getLabels(guid, guidString, termLabel);
}
// Set $scope to terms array
$scope.$apply(function () {
$scope.termsArray = termsArray;
});
}, function (sender, args) {
console.log(args.get_message());
});
// Get labels (synonyms) for each term and push values to array
function getLabels(termguid, guidString, termLabel) {
var clientContext = SP.ClientContext.get_current();
var taxSession = SP.Taxonomy.TaxonomySession.getTaxonomySession(clientContext);
var termStores = taxSession.get_termStores();
// The name of the term store. Note, that if you receive the following error "Specified argument was out of the range of valid values. Parameter name: index", you may need to check the term store name under Term Store Management to ensure it was not changed by Microsoft
var termStore = termStores.getByName("TermStoreName");
// GUID of Term Set from which to get the Terms
var termSet = termStore.getTermSet("TermSetGUIDHere");
var term = termSet.getTerm(termguid);
var labelColl = term.getAllLabels(1033);
clientContext.load(labelColl);
clientContext.executeQueryAsync(function () {
var labelEnumerator = labelColl.getEnumerator();
var synonyms = "";
while (labelEnumerator.moveNext()) {
var label = labelEnumerator.get_current();
var value = label.get_value();
synonyms += value + " | ";
}
termsArray.push({
termName: termLabel,
termGUID: guidString,
termSynonyms: synonyms
});
}, function (sender, args) {
console.log(args.get_message());
});
}
};
// Execute function
execOperation();
I have a Firebase structure like this:
user {
uid {
Lessons {
lid1 {
Title: ...
}
lid2 {
Title: ...
}
}
}
}
I want to use AngularFire to convert user as array so I can filter them using Angular like this:
var usersRef = new Firebase($rootScope.baseUrl + "users");
var userListfb = $firebase(usersRef).$asArray();
The problem is, I also need the number of child of the Lessons object. When I log the userListfb, it is an array. But inside the array, the Lessons node still an object. I can not user length to get its length. What is the correct way to find out the number of child of the Lessons Node with Firebase AngularFire?
Edit 1
According to Frank solution, I got an infinite loop (digest circle error from AngularJS).
The problem is, I will not know the "uid" key. I need to loop it in the first array to get the uid into the second firebaseArray.
Let's say I have a ng-repeat="user in users" in the view and call this on view level in each repeat:
{{getLessonLength(user.uid)}}
Then in the controller, I have this function:
$scope.users = $firebaseArray($scope.usersRef);
$scope.getLessonLength = function (uid) {
var userRef = $rootScope.baseUrl + "users/" + uid + "/lessons/";
var lessonsNode = $firebaseArray(new Firebase(userRef));
return lessonsNode.length;
}
}
And it throw this error: Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: []
All I want it is something like var lessonsCount = snapshot.child('lessons').numChildren() in regular Firebase .on('child_added' ...), the numChildren() function in FirebaseArray. Please help!
AngularFire contains quite some code to ensure that an ordered collection in your Firebase maps correctly to a JavaScript array as Angular (and you) expect it.
If you have a reference to a specific user, you can just create a new sync ($firebase) and call $asArray on that.
var usersRef = new Firebase($rootScope.baseUrl + "users");
var userListfb = $firebase(usersRef).$asArray();
var uid1LessonsRef = userRef.child('uid1').child('Lessons');
var uid1LessonsArray = $firebase(uid1LessonsRef).$asArray();
uid1LessonsArray.$loaded().then(function(arr) {
console.log('Loaded lessons, count: '+arr.length);
});
The data will only be synchronized once, no matter how many references you create to it.