How to get values and $id from $firebaseArray in angularJS - javascript

Hi I'm not a pro in firebase, just started working in it. After searching through many places I couldn't find solution to my problem.
My firebase database structure is as follow:
I want to retrieve data of a specific profile along with unique $id generated by firebase and.
$scope.login = function(users)
{
firebase.auth().signInWithEmailAndPassword(users.email, users.password)
.then(function(result)
{
var ref = firebase.database().ref("/profiles");
var examination = $firebaseArray(ref.orderByChild('uid').equalTo(result.uid));
console.log(examination);
and result I'm getting is
like this
Can anyone help me in this regard i.e. how to get values from result. Thanks In advance.

If you want to retrieve data and log it in your code, don't use AngularFire and stick to the JavaScript SDK:
$scope.login = function(users) {
firebase.auth().signInWithEmailAndPassword(users.email, users.password)
.then(function(result) {
var ref = firebase.database().ref("/profiles");
var examination = ref.orderByChild('uid').equalTo(result.uid);
examination.on('value', function(snapshot) {
console.log(snapshot.val());
});
You'll note that I added on('value', which is how you tell the Firebase SDK to start loading the data from the database. This and much more is covered in the Firebase documentation for web developers and I highly recommend that you read that end-to-end. A few hours spent there, will more questions than you imagine.
If you prefer sticking to AngularFire, then you should stop using console.log for checking loading status. From the AngularFire quickstart:
... $scope.data is going to be populated from the remote server. This is an asynchronous call, so it will take some time before the data becomes available in the controller. While it might be tempting to put a console.log on the next line to read the results, the data won't be downloaded yet, so the object will appear to be empty.
Instead, you can simply show the data directly in the HTML template:
The easiest way to log the data is to print it within the view using Angular's json filter. AngularFire tells the Angular compiler when it has finished loading the data, so there is no need to worry about when it be available.
<pre>{{ data | json }}</pre>
This last snippet comes from handling asynchronous operations in the AngularFire guide.

Use the $loaded() promise to see the value:
$scope.login = function(users)
{
firebase.auth().signInWithEmailAndPassword(users.email, users.password)
.then(function(result)
{
var ref = firebase.database().ref("/profiles");
var examination = $firebaseArray(ref.orderByChild('uid').equalTo(result.uid));
//console.log(examination);
examination.$loaded().then(function (exam) {
console.log(exam);
});
It is important to realize that invoking a $firebaseArray method immediately returns an empty array. Once the data is returned from the server the existing reference is populated with the actual data.
The $loaded() method returns a promise which is resolved when the array data has been downloaded from the database. The promise resolves to the $firebaseArray.

Related

Update view after AJAX call succeeds and returns data

I'm a beginner working on a recipe search app which returns a list of recipes based on the ingredients the user puts in the search bar. I'm learning to use Angular since it's convenient and makes my code more manageable.
So far I have succeeded in making jQuery Ajax GET requests to the API of my database and have a list of JSON objects returned.
Here's my Angular controller declaration:
var recipesData = []; // variable that will hold the returned data
angular
.module("awesomeapp")
.controller("listController", listController);
function listController () {
var vm = this;
vm.data = recipesData;
}
And I have stuff in vm.data displayed elsewhere in my view.
The problem is, when vm.data is set to recipesData, it doesn't contain anything yet because the page has just been loaded, the user hasn't put anything in and there isn't any data returned yet.
What should I do so that vm.data can be set after the Ajax call? Or can it be set outside of the listController function?
I'm looking for an elegant solution for this so that it makes everything easier to maintain. Thank you :)
The proper way to do this is to not use jQuery and use Angular's $http service to retrieve the data. The even more proper way to do this is to create your own service that internally uses Angular's $http service to get the data.
So first you would create the service. Something like this:
angular
.module("awesomeapp")
.service("recipeService", recipeService);
function recipeService($http) {
return $http.get(**url**)
}
Then your controller would look like something this:
function listController (recipeService) {
var vm = this;
recipeService.then(response) {
vm.data = response.data
}
}
You'll probably have more things on your service eventually, but that should get you going in the right direction. I'd highly recommend referring to John Papa's Angularjs style guide https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md for guidance on how to structure your app. You want to try to avoid using jQuery with Angular in general, but in particular, you want to avoid using it for things Angular does natively.

Test if value is the same of Firebase database

I have a realtime database in a Firebase project, with a registered value.
In a minigame, the device reads a QR-Code and store the information. So I want to send the value to Firebase, to the server test if value is the same of the database, and return just "true" or "false".
I can do this, but I get the value to the device and I perform the test in the client. My goal is just send the value and the server will perform the test.
I'm a newbie in Firebase, and I'm not sure if I can do this.
Assuming you have already linked Firebase to your app, you first need to make two references to your database:
var database = firebase.database(); //This links to your database
and
var nodeRef = firebase.database().ref("value/").child("IF APPLICABLE"); //This references to the node you want to compare.
Notice .child(). If the node you want is nested inside another node, you have to use .child("NODE HERE") to reference it.
Next to read the value, you would use:
nodeRef.on('value', function(snapshot) {
nodeValue = snapshot.val();
if (nodeValue == comparisonValue) {
//Do something
});
This calls on your reference and gets its value in your database. Then, within the if statement, you can execute the code that you want. You just have to make sure that they use the same word before the ".on".
Please ask if you need any more clarification!

Meteor: Data from External API call not rendering

I am relatively new to Meteor, and I'm trying to create a web store for my sister-in-law that takes data from her existing Etsy store and puts a custom skin on it. I've defined all of my Meteor.methods to retrieve the data, and I've proofed the data with a series of console.log statements... So, the data is there, but it won't render on the screen. Here is an example of some of the code on the server side:
Meteor.methods({
...
'getShopSections': function() {
this.unblock();
var URL = baseURL + "/sections?api_key="+apiKey;
var response = Meteor.http.get(URL).data.results;
return response;
}
...
});
This method returns an array of Object. A sample bit of JSON string from one of the returned Objects from the array:
{
active_listing_count: 20,
rank: 2,
shop_section_id: 1******0,
title: "Example Title",
user_id: 2******7
}
After fetching this data without a hitch, I was ready to make the call from the client side, and I tried and failed in several different ways before a Google search landed me at this tutorial here: https://dzone.com/articles/integrating-external-apis-your
On the client side, I have a nav.js file with the following bit of code, adapted from the above tutorial:
Template.nav.rendered = function() {
Meteor.call('getShopSections', function(err, res) {
Session.set('sections', res);
return res;
});
};
Template.nav.helpers({
category: function() {
var sections = Session.get('sections');
return sections;
}
});
And a sample call from inside my nav.html template...
<ul>
{{#each category}}
<li>{{category.title}}</li>
{{/each}}
</ul>
So, there's a few things going on here that I'm unsure of. First and foremost, the DOM is not rendering any of the category.title String despite showing the appropriate number of li placeholders. Secondly, before I followed the above tutorial, I didn't define a Session variable. Considering that the list of shop categories should remain static once the template is loaded, I didn't think it was necessary from what I understand about Session variables... but for some reason this was the difference between the template displaying a single empty <li> tag versus a number of empty <li>'s equal to category.length --- so, even though I can't comprehend why the Session variable is needed in this instance, it did bring me one perceived step closer to my goal... I have tried a number of console.log statements on the client side, and I am 100% sure the data is defined and available, but when I check the source code in my Developer Tools window, the DOM just shows a number of empty li brackets.
Can any Meteor gurus explain why 1) the DOM is not rendering any of the titles, and 2) if the Session variable indeed necessary? Please let me know if more information is needed, and I'll be very happy to provide it. Thanks!
You set the data context when you use #each, so simply use:
<li>{{title}}</li>
If a Session is the right type of reactive variable to use here or not is hard to determine without knowing what you are doing but my rough guess is that a Mini Mongo collection may be better suited for what it appears you are doing.
To get you started on deciding the correct type of reactive variable to use for this head over to the full Meteor documentation and investigate: collections, sessions, and reactive vars.
Edit: To step back and clarify a bit, a Template helper is called a reactive computation. Reactive computations inside of helpers will only execute if they are used in their respective templates AND if you use a reactive variable inside of the computation. There are multiple types of reactive variable, each with their own attributes. Your code likely didn't work at all before you used Session because you were not using a reactive variable.

Ember filtered model entries count

I'm trying to get the number of results of the Ember Data Store filter. E.g
var users = this.store.filter('relevantUser', function(user)
{
return user.get('screenName') == screenName;
});
return user.get('length');
But this always seems to return 0. What am I doing wrong?
I think it should be users.get('length');.
Things to make sure when using filter method of the store.
First argument is the model type. Assuming you have a model named App.RelevantUser then your query is fine, else if the model is App.User then you should be using 'user'.
The var users is actually a DS.PromiseArray instance and not an array actually. Try doing this
this.store.filter('relevantUser',function(user){return user.get('screenName')==screenName}).then(function(relevantUsers){console.log(relevantUsers.get('length'))})
As store.filter queries the server too we need to wait for the promise to resolve before accessing the results. Otherwise they would be always 0.
Incase you are using Chrome. Open up Network Tab in Dev Tools and check the network request going to the server when you run the filter query.

Identify object in angular js has changed

I have a backend object that i receive from the server and sent to server.
I give a permission to my users to change the backend object.
I would like to identify if the backend object has changed from the save point.
How can i identify it?
For example:
I have a module called
app.controller('PanelCtrl', function($scope, $http) {
$scope.action = "";
$scope.selectedItem = "";
$scope.compoundItem = [];
...
I have in the compound item array of Objects.
I would like to know if something is changed whether the change occures in the primitives and whether in the compoundItem...
Edit: two scenarios 1) client check (the original post) 2) server check (extended based on the comments)
1) check on the Client
do not worry about performance of the below steps. And if you do, please read more about performance here
The answer is: angular.equals() and a similar scenario is described here: Developer Guide / forms (it is about validation). In the section Binding to form and control state, we can see the script (an extract):
function Controller($scope) {
$scope.master = {};
$scope.update = function(user) {
$scope.master = angular.copy(user);
};
$scope.reset = function() {
$scope.user = angular.copy($scope.master);
};
$scope.isUnchanged = function(user) {
return angular.equals(user, $scope.master);
};
}
What we can see here, is what we need. Firstly copy the source state (inside the update function). We can change isUchnaged any time, while using the angular.equals()
Also check Compare objects in Angular
NOTE: A comment to the angular.copy(). I found, that in some cases, better is to use the lo-dash .deepClone()
2) Server side solution
In case that (as Dalorzo expects) are interesting in the comparison of the server, persisted version and the client. It could make sense, if we want to check if some one else has already changed the "Entity". In some other transaction
There are in general many techniques, but the most effective is versioning. On the persistence layer, we have to introduce some value, which is changed/incremented every time the "Update" is executed. In case of MS SQL Server it would be the rowversion, see more here
Then, during any sucesfull UPDATE operation, this version will be changed, and we know that data on the client are stale... there are newer on the server.
Summary with version:
Our check could be very easy:
Compare the Client (current) Version property and
ask the server for the latest persisted.
This is a standard way I am using with NHiberante (read more here)
The first solution that comes to my mine is to use
$timeout(isDifferent,xtime)
where:
isDifferent= is your custom function to get the backend object or identify when it has changed.
xtime= is and integer value in milliseconds which represents how often your function will execute.

Categories