AngularFire $add not resolving promises - angularjs

I have a simple bit of code adding an object to a $firebaseArray() like this:
var itemRef = database.ref('/somelist/of/items');
$scope.list = $firebaseArray(itemRef);
$scope.list.$add({name:"new item1"}).then(function(newItem) {
console.log("I wish this log would show up");
}).catch(function(er) {
console.log("This doesn't run either");
}).finally(function(res) {
console.log("Added just to be sure, but also doesn't get here");
});
I've initialized firebase, and the $add() function works perfectly (as well as all of the other features, including Auth and Storage).
However, I need the key for the added item and the promise is never executed. My original attempt was based on the link below but I cannot even execute the simplified code above.
The original attempt:
https://www.firebase.com/docs/web/libraries/angular/api.html#angularfire-firebasearray-addnewdata
I tried to set up a plunker or jsfiddle to demo the error but, I feel like an idiot because I'm getting X-origin issues on both platforms.

I spoke directly with the AngularFire folks and there is a bug with version 2.3.0 where it has compatibility issues with firebase 3.7.1.
For ref:
https://github.com/firebase/angularfire/issues/922

Related

AngularFire - Get a firebaseObject for each item in a firebaseArray ng-repeat

I have an ng-repeat which is connected to a firebaseArray which is an index of a user's doc Ids.
I want to display a list of their docs with additional info for each one, e.g. it's title and description.
My firebase structure is:
+users
- userId1
-theirDocs
-docId1: true
-docId2: true
+docs
-docId1
- tile
- description
- url
-docId2
- etc etc
I've tried everything and still can't get this to work, it seems a pretty common use case. I've tried using a function that calls a firebaseObject each time. I've tried using a separate controller. I've tried a directive, I've even tried using firebase.utils library (I think out of date now).
Can anyone recommend the best way to do this using AngularFire? Thanks in advance!
It would be better to see a code snippet as to fully understand what you've tried first of all, as it's difficult to determine where the issues lie. That being said, as long as your rules are not preventing this, you may need to wait for the data to download using $loaded function beforehand.
EXAMPLE
This example is clearly available by following this link, yet here is an example for further clarity:
var yourFirebaseReference = firebase.database().ref("REPLACE WITH YOUR FIREBASE BRANCH HERE");
var data = $firebaseArray(yourFirebaseReference);
data.$loaded().then(function(x) {
console.log(data) // Example, you can do what you want with your 'data' now as the data has loaded
x === data; // true
}).catch(function(error) {
console.log("Error:", error);
});

Why calling different subscription on the same collection cause error in meteor?

I working on this angular-meteor tutorial step 12
an I have a question in
Stopping a subscription Topic
you can use ctrl+f using "meteorSubscribe"
then the key sentence on that topic is
The reason is that we are calling a different subscription on the same collection inside the partyDetails controller.
the code before correction is
$scope.party = $meteor.object(Parties, $stateParams.partyId).subscribe('parties');
$scope.users = $meteor.collection(Meteor.users, false).subscribe('users');
then after correction
$scope.party = $meteor.object(Parties, $stateParams.partyId);
$scope.users = $meteor.collection(Meteor.users, false).subscribe('users');
$scope.$meteorSubscribe('parties');
I try to run before correction code and nothing(error) show in cmd but it just cause the wrong result as tutorial say
if you navigate to the party details page and then go back, pagination and search will stop working.
Then i got two question
Why no error show on cmd?
Why error from partyDetails controller affect to partiesList controller search and pagination? What is their relation?
EDIT: If you don't cancel a subscription, then if you navigate away and back again you will end up trying to subscribe twice to the same publication, resulting in the error, because subscriptions in meteor last until you end them.
There are two ways to get rid of a subscription with angular-meteor. One you can assign a handle variable to the subscription and then on navigating away from the page you can stop it. Two (the recommended way) is to use $scope.$meteorSubscribe instead of $meteor.subscribe() because it is set up to automatically remove the subscription when the scope is destroyed.
I can't see all of your code to know for sure why you are or are not getting the errors you think you should, hopefully this sheds some light on what is going on in the tutorial.
The very end result would be something like:
$meteor.autorun($scope, function() {
$meteor.subscribe('parties', {
limit: parseInt($scope.perPage),
skip: parseInt(($scope.page - 1) * $scope.perPage),
sort: $scope.sort
}).then(function() {
$scope.partiesCount = $meteor.object(Counts, 'numberOfParties', false);
$scope.parties = $meteor.collcetion(function() {
return Parties.find({}, {
sort: $scope.getReactively('sort');
});
});
});
});
Notice that he's also changing the publish function on the server. It helps to understand if you click the links to show the git diffs.

How to disable firebase 3-way data binding

I am using angularJS 1.3 with angularfire and firebase.
I did create some factories that encapsulate the firebase object, and it works very well. The 3 way data binding is really cool.
I am planning to build a large application using firebase for data persistance, but I am facing a massive issue :
In my business model, I want some models/collections to support 3-way data binding, but I want other collections not to be updated live.
Some clients visiting the resulting website might be scared when they see the website's content being updated live - and I don't want that.
Imagine you are reading an article , somehow long and complexe, and you put your attention into a paragraph which you have issues understanding, and suddenly, the paragraph disappears and is replaced by a new one. Now imagine that you have no idea about web development. You might start to think to consult some professionnal about your mental health, or think your computer is hacked. Who knows !
So I would like to disable the 3 way data binding for this article, and avoid this border-line client phone calls. The only solution I found would be not to use fireangular, and use the beyond angularfire documentation section instead, and remove the following lines :
ref.on("value", function(snapshot) {
$timeout(function() {
$scope.data = snapshot.val();
});
});
This would fix the issue, but then in my admin interface, I would have to implement a second Factory so admin users can access the 3 way data binding for articles - Which is not very DRY.
In my artitcle controller, I would have to write something like this :
$scope.loadArticle = function(){
if(UserService.type === 'admin'){
AdminArticleFactory.get(id);
}
else{
ArticleFactory.get(id);
}
}
Is there any other way of setting up firebase to disable the pull updates?
Yeah, that is what I also ran into. Sometimes you will repeat yourself with Firebase. Also when storing data. I would recommend just making a function to save the data that you don't want to be updated instantly.
<button ng-click="saveChanges">save</button>
In controller
$scope.saveChanges = function () {
var obj = $firebaseObject(ref);
obj.foo = "bar";
obj.$save().then(function(ref) {
ref.key() === obj.$id; // true
}, function(error) {
console.log("Error:", error);
});
}
edit
To desync a firebase object/array you can follow this answer: How to disassociate angularFire bound object?

$on('value...) gives me "undefined is not a function" in angularfire

I have started to use angularjs and now am following a tutorial about angularjs with angularfire. In the tutorial there is a section to learn how to use child_added
angular.module('firebaseApp').service('MessageService', function(FBURL, $q, $firebase) {
var messageRef = new Firebase(FBURL).child('messages');
var fireMessage = $firebase(messageRef).$asArray();
return {
childAdded: function childAdded(limitNumber, cb) {
fireMessage.$on('child_added', function(snapshot){
console.log(snapshot);
var val = snapshot.val();
cb.call(this,{
user: val.user,
text: val.text,
name: snapshot.name()
});
});
},
and main controller :
MessageService.childAdded(5, function(addedChild){
$timeout(function() {
$scope.messages.push(addedChild);
});
});
When I use the code, chrome developer tools is giving an error :
TypeError: undefined is not a function
adressing .$on in MessageService and .childadded in controller.
This is a video tutorial and I can see him working like this. I checked many answers but could not find a way. My best shot is I guess different versions of angularjs and angularfire. But that did not help me either. Can you help me to solve it?
Thank you in advance.
I thought I'd offer a bit of clarity on the topic for those who are taking this tutorial on tutsplus. First, we should pay attention to the versions of firebase and angularfire that we are using, compared to what the instructor is using. This might seem obvious, but there are many out there who fail to realize it. Whenever watching a tutorial, you should always check the version of ANY package you are using. This world of software moves really fast, and up-to-date tutorials are a luxury.
Pay attention to your bower.json file in your project. Note the version of the following lines:
"firebase": "~2.0.4",
"angularfire": "~0.9.0"
You can see here the version of the dependencies I used. Chances are, you were like me, and your version will differ from what you find in the teacher's version. The instructor offers his source files on the course main page. Download those files, which should be titled SourceFiles_RTWebAppAngularFirebase.zip. Once downloaded, open it, and you will see a list of packaged zip files contained in a file called Firebase Source. Find lesson-16-angularfire.zip, and also open it. A folder titled "Firebase" should be provided, and there you will find the instructor's app that he created during the tutorial. Check out his bower.json file, and check it against what you have. According to what I found, both versions of firebase and angularfire were vastly different. This means only one thing: we have some reading to do.
Go here and check out the releases of AngularFire: https://github.com/firebase/angularfire/releases
Scroll down, and read the release notes of v0.8.0. A very important note is found here.
$on() and $off() no longer exist. Similar functionality can be obtained with $watch() but should be discouraged for trying to manually manage server events (manipulation should be done with data transformations through $extendFactory() instead).
Obviously now, we understand that we can't follow blindly in the instructor's footsteps. We have to try mimicking his app's functionality. Reading what I posted above, we can use $watch to obtain similar functionality. However, I honestly tried to make this work, and the functionality that $watch delivers is not exactly the functionality we are trying to achieve. Ideally, we should synchronize our empty messages array $scope.messages with $firebase(messageRef).$asArray(). That wouldn't be as fun though.
The route I took was this: I looked at what cb.call() was doing, which is the following
MessageService.childAdded(function(addedChild) {
$scope.messages.push(addedChild);
});
This call back function pushes an object created from cherry picked values obtained from a snapshot returned from a 'child_added' event. The real leverage here is the snapshot, which is provided by the $firebase module itself with Firebase.on(). If you read the docs for the "Child_Added" event, it says
This event will be triggered once for each initial child at this location, and it will be triggered again every time a new child is added. The DataSnapshot passed into the callback will reflect the data for the relevant child
The DataSnapshot returned for every "initial" child at this location, is what initially populates the list of messages. This means that we can change this:
fireMessage.$on('child_added', function(snapshot){
console.log(snapshot);
var val = snapshot.val();
cb.call(this,{
user: val.user,
text: val.text,
name: snapshot.name()
});
});
back to this:
messageRef.on('child_added', function(snapshot) {
var val = snapshot.val();
cb.call(this,
user: val.user,
text: val.text,
name: snapshot.key()
});
});
The messages should populate again on the front page. Your code should be stable enough as well to follow the instructor during the remainder of the Refactor lesson.

AngularJS $http success but not working

i'm using angularJS and SLIM PHP restful server, the PHP service is working and actually i have already used $http.get() with no problems in this application ...
But now a strange thing is happening, i created a new function in the same way that the others, and it get .success(function(data)) with no problems, i actually can console.log(data) and it shows the right results, but when .success() finish and return, i recieve a undefined result.
ps: there is no error in browser console.
var markerOptions = [];
loadMarkers();
console.log(markerOptions);
function loadMarkers() {
$http.get('http://localhost/rest/getMarkers').success(function(response){
console.log(response);
markerOptions = response;
});
}
Console.log() inside success() return the right data
Console.log() after loadMarkers() return undefined
#MarcKline's comments are correct. Anyways, following what I think you're trying to achive by this piece of code of yours, you can assign the returned data from the ajax response to a scope variable (assuming you're using $scope), e.g $scope.markerOptions = response. You can declare markOptions as a scope variable by var $scope.markOptions = [] (...and, of course, log it by console.log($scope.markOptions) accordingly). Also, define $scope.loadMarkers = function() {...} and call it by $scope.loadMarkers()
The scope will be updated as soon as the client-side gets its ajax response.
Hope it helps your current needs in addition to a better understanding of javasciprt's async approach that some of its principles were explained to you by the comments.

Resources