Firebase's internal request function returns null

I am trying to create a Tracker Attendance Attendance Attendance Attendance app with javascript with firebase.

But I have a problem, I'm trying to execute a request inside a function and return the function to this data.

But when I try, it returns nothing. undefined

Here is my code

var root = 'https://path.firebaseio.com'; function initFireSubjects(){ var db = {}; db.connection = new Firebase(root + '/subjects'); db.addSubject = function (year, code, name) { this.connection.child(year).push({ code: code, name: name }); }; db.getAll = function (year) { var value; this.connection.child(year).on('value', function (snapshot) { value = snapshot.val(); }); return value; }; } 

And here is my code to check it

 var db = initFireSubjects(); var test = db.getAll('2014'); console.log(test); 

The data structure looks like this:

 subject:{ '2014':{ randomKey1:{ code:'eng1', name:'English 1' }, randomKey2:{ code:'math1', name:'Mathematics 1' }, randomKey3:{ code:'sci1', name:'Science 1' } }, '2015':{ randomKey4:{ code:'polsci1', name:'Political Science 1' }, randomKey5:{ code:'comprog', name:'Computer Programming' } } } 

The thing is, I can pull data if I do it like this

 db.getAll = function(year){ var value; this.connection.child(year).on('value',function(snapshot){ value = snapshot.val(); console.log(value); } } 

I do not know why it cannot retrieve data in an object oriented manner.

Any input?

Thanks.

+1
source share
1 answer

What you see has little to do with OO, but all because Firebase (like most modern websites) is asynchronous in nature.

When you register an event handler with Firebase using on , Firebase begins to retrieve and track data at that location. Since it may take some time to receive data (and updated data may appear at any time), the browser continues to execute your JavaScript. Once the data is available, the callback function is called.

It’s a little easier to understand what happens if we write your code a bit:

 /* 1 */ db.getAll = function (year) { /* 2 */ var value; /* 3 */ this.connection.child(year).on('value', db.onValue); /* 4 */ return value; /* 5 */ }; /* 6 */ db.onValue = function(snapshot) { /* 7 */ value = snapshot.val(); /* 8 */ console.log(value); /* 9 */ }); 

When your getAll function getAll executed, it first declares a value variable. On line 3 it tells Firebase to call db.onValue when it receives the year value from the server. Firebase shuts down to get this value, but your JavaScript continues to run. So, on line 4, you return a value that is still not initialized. So you return undefined .

At some point, the price you requested is returned from Firebase servers. When this happens, the onValue function is onValue and prints the year on line 8.

One thing that can help you understand why this is useful: if the other is now updating the year in your Firebase, the onValue function will be called again. Firebase not only retrieves data once, but also tracks the location of changes in the data.

Asynchronous loading is not unique to Firebase. Almost everyone who started programming for the modern web in JavaScript will bite this at some point. The best thing you can do is accept and accept asynchrony (is that even a word?) Quickly and deal with it.

Working with it usually means that you are moving the operation you want to perform with the new values ​​inside the callback function. Thus, console.log , which I added on line 8, can also update your interface with something like document.querySelector('#currentyear').textContent = value .

Also read this answer (it uses AngularFire, but the problem is the same): Asynchronous array access in Firebase and there are some other related issues.

+3
source

All Articles