Zaid Mirza Zaid Mirza - 1 month ago 18
AngularJS Question

Firebase Sync handling

I have data structure like below:

-Company
|
-jskdhjJKHh-Yty
-companyName:CompanyTH

-Employees
|
-shdjasjdshy665-333
|
-empName:Peter
|
-Company
-jskdhjJKHh-Yty:true


Im pushing data of
Employees
like below in
ParentController
:

Step 1:

var ref=firebase.database().ref("Employees");
var newKey=ref.push({empName:"John"}).key


Setup 2:

var childCompany=ref.child(newKey+'/Company');
childCompany.set(true);


Step 3:

$scope.emplist=$firebaseArray(ref);


In
HTML
:

<div ng-repeat="emp in emplist" ng-Controller="ChildController">
<p>{{emp.empName}}</p>
<p>{{CompanyName}}</p>
</div>


In
ChildController
:

var companyRef=firebase.database().ref("Company/"+Object.keys($scope.emp.Company)[0]);
$scope.CompanyName=$firebaseObject(companyRef);


Problem is :

When
Step 1
executed it sync data to
$scope.emplist
and
ChildController
executed for that
ng-repeat
instance and when code in
ChildController
try to execute line
Object.keys($scope.emp.Company)[0]
it gives error that
Company
is not defined. This error is beacause
Step 2
is not executed and
firebase
sync data after
Step 1
.But when
Step 2
is executes it updates
firebase-database
but
ChildController
does not executes on updatation of
ng-repeat
instance.

One Solution in my mind that somehow Can I stop
Firebase
to sync data until all push queries finish? or any of you guys have any other solution?

One thing to note:

Above mentions steps executes successfully when I run it 2nd time again in same session of application, it is strange that it don't run in first attempt.

Answer

If I have understood your problem correctly, then you might have to change your push logic a bit.

Its always handy to save data in a specific node in Firebase in a single push command. As far as I can see, you're trying to push the data Employees node in two steps. Is it really necessary? You can easily push the empName and the childCompany at once using a single push.

And in your ChildController, you need to add a listener to that node from where you're trying to fetch the data using ref.on. So that you get a callback after a successful store of the data in your Firebase database.

var companyRef=firebase.database().ref("Company/"+Object.keys($scope.emp.Company)[0]);
companyRef.on("value", function(data) {
  // This will be triggered once there's a
  // change in data in the node the reference is referring to
  doSomething();
});

Update

then how I can use set(true) within push?

Take a single object containing both empName and childCompany. Then just use push like this.

// Get the firebase reference of your node
var ref = firebase.database().ref("Employees");

// Create an object first. 
var employee = {
  empName: "Peter",
  company: "CompanyTH"
};

// Pass the object that you've prepared earlier here. 
ref.push.set(employee);

This is just an example. You can have nested object. The idea is to passing the whole object at once and add a callback on successful save in Firebase. You might think of something like this too.

ref.set(employee, function(error) {
  if (error) {
    doSomethingOnError();
  } else {
    doSomethingOnDataSavedSuccessfully();
  }
});

You can try building nested classes like this

var employee = {
  empName: "Peter",
  Company: {
    companyName: "Name",
    uniqueID: true
  }
};