_.each and Collection.each error - backbone.js

I'm playing around with the Todos example for backbone.js, but the toggleAllComplete function is not iterating over the collection when I run save. However, when I instead alert the title, it iterates over the whole collection.
toggleAllComplete: function () {
var done = this.allCheckbox.checked;
Todos.each(function (todo) {
/* this doesn't iterate over the collection */
// todo.save({'done': done});
/* this does */
alert(todo.get('title'));
});
}
Why?
I've also tried this with _.each(Todos.models, function(todo) { but the same problem persists.
When I use developer tools in chrome, I see that I have an Uncaught Type Error: Converting circular structure to JSON on this line in backbone-localstorage.js
this.localStorage().setItem(this.name+"-"+model.id, JSON.stringify(model));

If there's an error saving, then it's probably stopping each from going over every model. When you do an alert, there's no error, so it lets each do its job.
You could try throwing in some callbacks on the save method to see if that helps you debug.
todo.save({'done': done}, {
success: function() { console.log(["success", arguments]); }
error: function() { console.log(["error", arguments]); }
});

Related

Firestore TypeError: collection().where() is not a function

I am trying to filter my docs in firebase firestore by checking if a doc 'users' array contains the user's email address. The 'chat' collection contains docs with ids: 'user#email.com:friend#email.com' and a doc contains messages and users stored in array.
I would like to list chats for the current user.
The problem is that every time I would like to use the where() clause I get to following error:
TypeError: firebase_app__WEBPACK_IMPORTED_MODULE_1___default.a.firestore(...).collection(...).where(...).onSnapshot(...).catch is not a function
This is my code:
firebase.firestore().collection("chats").where("users", "array-contains", currentUser.email)
.onSnapshot(async res => {
setChats(res.docs)
})
.catch(function (error) {
console.log("Error getting documents: ", error);
});
After read the "onSnapshot" method reference I understood it does not return anything. The method signature has a void return. You may have to pass the callback you want to be called as parameter of the onSnapshot method.
Actually you have an exemple in the Firestore documentation at the Handle listen errors section.
Bellow the snippet of code from the documentation:
db.collection("cities")
.onSnapshot(function(snapshot) {
// Handle changes
}, function(error) {
// Handle errors
});
I have same issue.I just not imported "where" method,couse when you click CTRL+space it is not showing for imports,and automatically it is not imports,I just written it by my hand.and it`s worked..

kinvey fetching and remove not working (AngularJS)

I have this problem with kinvey backend,
I'm trying to fetch data from my collection but it doesn't work for me. here is my code :
var query = new $kinvey.Query();
query.equalTo('_id', '5909e8084c68b1ef74fa4efc');
var dataStore = $kinvey.DataStore.collection('User1Bases', $kinvey.DataStoreType.Network);
var stream = dataStore.find(query);
stream.subscribe(function onNext(entity) {
// ...
}, function onError(error) {
// ...
}, function onComplete() {
//...
});
Can you help me please
If you let run the code you have posted then consider four things:
Make sure you have Kinvey implemented:
<script src="https://da189i1jfloii.cloudfront.net/js/kinvey-html5-sdk-3.10.2.min.js"></script>
Make sure you have initialized the Kinvey service before:
// Values shown in your Kinvey console
Kinvey.init({
appKey: '<your_appKey>',
appSecret: 'your_appSecret'
});
Make sure you are logged in with a user that has the rights to read your collection (should be fine using the All Users role (default)):
var promise = Kinvey.User.login('<username>', '<password>')
.then(function() {
console.log ("You are logged in");
})
.catch(function(error) {
console.log (error);
});
Output the return result to see whats coming back. To make sure you do the query AFTER successful login, paste you query inside the .then function of login.
I'm not sure if your query is valid unter 3.x since a lot has changed and I'm not working with older Kinvey versions.
So that all together would look like this:
// Initialize Kinvey
Kinvey.init({
appKey: '<your_appKey>',
appSecret: 'your_appSecret'
});
// Login with already registered user
var promise = Kinvey.User.login('<username>', '<password>')
.then(function() {
console.log ("You are logged in");
// Your query
var query = new $kinvey.Query();
query.equalTo('_id', '5909e8084c68b1ef74fa4efc');
var dataStore = $kinvey.DataStore.collection('User1Bases', $kinvey.DataStoreType.Network);
var stream = dataStore.find(query);
stream.subscribe(function onNext(entity) {
// Output of returning result
console.log (entity);
// ...
}, function onError(error) {
// ...
}, function onComplete() {
//...
});
})
.catch(function(error) {
console.log (error);
});
There are now three return sets possible:
Nothing (as you say) -> Something missing/wrong in the code (compare yours with mine)
Empty array: Your query didn't find anything, adapt the search value(s)
One or more entries in the array -> All fine, what you were looking for!
Hope that helps!
When querying by _id there is a built in method: http://devcenter.kinvey.com/angular/guides/datastore#FetchingbyId
Try switching to var stream = dataStore.findById('entity-id');
Also check to make sure you don't have any preFetch or postFetch BL that is interfering with the query.

Mongoose adding select prevent returning to client

Got the following code:
On AngularJS client:
var getDocs = function() {
return $http.get('/api/docs/list')
.then(function(result) {
return result.data; // bookmark1 line
});
}
On Node.Js BE:
function getDocs() {
return Doc.find({}).exec()
.then(function success(docs) {
return res.send(docs);
});
}
Works perfectly.
When I change the first line in getDocs() to
return Doc.find({}).select('-field1 -field2').exec()
I see the docs after the query execution without the fields (as expected) but for some reason The http is pending and chrome debugger is not stopping on the success callback of the client (bookmark1 line).
Edit:
Changed to
return Cv.find({}).select('-field1 -field2').exec(function success(err, cvs) {
return res.send(cvs);
});
Got the following error in client:
Solution:
Well It turn out I had another field which depends on field1
docSchema.virtual('field3').get(function () {
return this.field1.toString("base64");
});
It fails and for some reason it didnt appear on my IDE.
I Added a null check and that solve the problem.
Not sure if I should remove this question or maybe it has value for other people. Feel free to say what you think.

Wait for page redirection in Protractor / Webdriver

I have a test that clicks a button and redirects to a user dashboard. When this happens Webdriver returns:
javascript error: document unloaded while waiting for result.
To fix this I insert browser.sleep(2000) at the point where redirection occurs and assuming my CPU usage is low, this solves the issue. However, 2000 ms is arbitrary and slow. Is there something like browser.waitForAngular() that will wait for the angular to load on the redirected page before the expect(..)?
it('should create a new user', () => {
$signUp.click();
$email.sendKeys((new Date().getTime()) + '#.com');
$password.sendKeys('12345');
$submit.click();
browser.sleep(2000); // Need alternative to sleep...
// This doesn't do it...
// browser.sleep(1);
// browser.waitForAngular();
$body.evaluate('user')
.then((user) => {
expect(user).toBe(true);
});
});
do you think something like this could work for you? This will wait up to 10 seconds for the url to include the text 'pageTwo', or whatever you put in.
var nextPageButton = $('#nextPage');
nextPageButton.click().then(function(){
return browser.driver.wait(function() {
return browser.driver.getCurrentUrl().then(function(url) {
return /pageTwo/.test(url);
});
}, 10000);
};
Just stick in the regex of the url you are expecting.
Alternatively, you could wait for an element from the next page to appear as well:
var nextPageButton = $('#nextPage');
nextPageButton.click();
var elementFromSecondPage = $('#coolElement');
browser.wait(protractor.until.elementIsVisible(elementFromSecondPage), 5000, 'Error: Element did not display within 5 seconds');
When using .click, protractor will naturally wait for angular to finish the action attached to the click, such as changing the page. But, while the page change, you may still be needing something specific to be loaded, so the test fails before that part is available. Using this, it should wait for the click part to finish, then wait for the element to appear.
To expand on user2020347's answer:
Thanks that solved my issue. I wonder why this isn't a built in function. I'll be using this in many places to wait for browser navigation.
To make it more concise, I made a little helper:
Object.assign(global, {
waitUntilURLContains: string => {
let fn = () => {
return browser.driver.wait(() => {
return browser.driver.getCurrentUrl().then((url) => {
return url.includes(string);
});
}, waitDelay);
}
return fn.bind(null, string);
}
});
In my test:
$button.click().then(waitUntilURLContains('dashboard'));
keeping it very simple. I was also running into the same problem but was able to solve it using the following code :
page.setUsername(objectrepository.userdetails.useremail);
page.setPassword(objectrepository.userdetails.userpassword);
page.login().click();
**browser.wait(EC.visibilityOf(page.greetingMessageElement()), 5000);**
page.greetingMessageElement().getText()
.then(function (value){
expect(browser.getCurrentUrl()).toContain("#/mytickets");
});

Creating and adding to arrays in angularFire / Firebase

I am trying to build an app with angularjs and Firebase similar to a forum for helping my classmates with problems. I also want people to be able to 'reply' to the specific problems the classmates are having, so I create an object with many values in the angularjs factory, like this:
factory.addError = function() {
factory.errors.$add({
...
replies: []
});
};
The problem with this is that Firebase doesn't save parameters with empty values for placeholders, such as the parameter 'replies' above. I have tried to hard code a placeholder value into the array, but that seems like a very patchy solution, and that comes with it's own set of problems for me having to delete out the data in Firebase. For reference, here is the code in the linked controller:
$scope.error.replies.$push({
name: $scope.replyName,
message: $scope.replyMessage,
time: (new Date()).toString(),
upvote: 0
});
How do you initialize an empty array into the object? And will $push properly use Firebase's commands to save it to it's own set of data?
First, here are some relevant resources and suggestions:
Resources
Check out Firebase's blog post, Best Practices: Arrays in Firebase - "Arrays are evil".
Also, the AngularFire Development Guide.
And the documentation for AngularJS providers.
Suggestions
As the AngularFire API Documentation says:
"There are several powerful techniques for transforming the data downloaded and saved by $firebaseArray and $firebaseObject. These techniques should only be attempted by advanced Angular users who know their way around the code."
Putting all that together, you accomplish what you want to do by:
Extending AngularFire services, $firebaseArray and $firebaseObject.
Following the documentation for extending services.
Example
Extended Error $firebaseObject
.factory('Error', function(fbUrl, ErrorFactory) {
return function(errorKey){
var errorRef;
if(errorKey){
// Get/set Error by key
errorRef = new Firebase(fbUrl + '/errors/'+errorKey);
} else {
// Create a new Error
var errorsListRef = new Firebase(fbUrl + '/errors');
errorRef = errorsListRef.push();
}
return new ErrorFactory(errorRef);
}
})
.factory('ErrorFactory', function($firebaseObject){
return $firebaseObject.$extend({
sendReply: function(replyObject) {
if(replyObject.message.isNotEmpty()) {
this.$ref().child('replies').push(replyObject);
} else {
alert("You need to enter a message.");
}
}
});
})
Error Controller
.controller('ErrorController',function($scope, Error) {
// Set empty reply message
$scope.replyMessage = '';
// Create a new Error $firebaseObject
var error = new Error();
$scope.error = error;
// Send reply to error
$scope.reply = function(){
error.sendReply({message:$scope.replyMessage});
}
})
And String.prototype.isNotEmpty()
String.prototype.isNotEmpty = function() {
return (this.length !== 0 && this.trim());
};
(adapted from this answer)
Hope that helps!

Resources