Javascript object method does not update variable - javascript

var myUser = (function () {
var username = "",
var isConnected = false;
return {
setUsername: function (n) {
username = n;
},
setConn: function (connStatus) {
isConnected = connStatus;
},
user: username,
isCon: isConnected
};
}());
When I call
myUser.setUsername("user123");
username variable does not get updated.
Any advice?

It looks like you want to use myUser.user to refer the updated username value.
However, if that's the case, it doesn't work. setUsername updates username variable, but myUser.user only points to username's initial value, which is "". It won't points to the updated username value
to fix the problem, you can change
user: username,
to
user: function() {
return username;
},

This might be a better case to use prototype model:
function User(prop) {
prop = prop || {};
this.username = prop.username || '';
this.isConnected = prop.isConnected || false;
}
User.prototype = {
setUser: function(uname) { this.username = uname; },
setConn: function(status) { this.isConnected = status; }
};
var myUser = new User();
myUser.setUser('user1234');
// OR
var myUser = new User({ username: 'user1234' });
console.log(myUser.username); //=> 'user1234'

....
},
user: username,
isCon: isConnected
user: username forces the username to be evaluated, which returns "". This is more easy to figure out what happend
var obj = {
log: console.log("printed when init")
}

Related

How to create user specific data when user logs in for the first time in realtime firebase database?

I want the code to behave such that it creates specific data when user is signed in but doesn't create it if already present in the firebase real-time database.
I have used the following code through which i check if the child is already present or not and if not then creates the child in firebase database, but somehow the code isn't behaving as it should.
Whenev the user logins again the complete data part is rewritten.
Snippet I need help in
if (!(checkdata(user.uid))) {
writeUserData(user.uid,user.displayName,user.email,user.photoURL)
}
var database = firebase.database();
function checkdata(userid){
var ref = firebase.database().ref("users");
ref.once("value")
.then(function(snapshot) {
var datapresent = snapshot.hasChild(userid); // true
return datapresent
});
}
function writeUserData(userId, name, email, imageUrl) {
firebase.database().ref('users/' + userId).set({
username: name,
email: email,
profile_picture : imageUrl,
cropdata : []
});
}
Complete JS file
const signInBtn = document.getElementById('signinbtn');
const signOutBtn = document.getElementById('signoutbtn');
const userDetails = document.getElementById('username');
const auth = firebase.auth();
const provider = new firebase.auth.GoogleAuthProvider();
signInBtn.onclick = () => auth.signInWithPopup(provider);
signOutBtn.onclick = () => auth.signOut();
function toggle(className, displayState){
var elements = document.getElementsByClassName(className)
for (var i = 0; i < elements.length; i++){
elements[i].style.display = displayState;
}
}
auth.onAuthStateChanged(function(user) {
if (user) {
// signed in
toggle('userishere', 'block');
toggle('usernothere', 'none');
//userDetails.innerHTML = `<h3>Hello ${user.displayName}!</h3> <p>User ID: ${user.uid}</p>`;
userDetails.innerHTML = `Hello ${user.displayName}!`
console.log(user)
if (!(checkdata(user.uid))) {
writeUserData(user.uid,user.displayName,user.email,user.photoURL)
}
} else {
// not signed in
toggle('userishere', 'none');
toggle('usernothere', 'block');
userDetails.innerHTML = '';
}
});
var database = firebase.database();
function checkdata(userid){
var ref = firebase.database().ref("users");
ref.once("value")
.then(function(snapshot) {
var datapresent = snapshot.hasChild(userid); // true
return datapresent
});
}
function writeUserData(userId, name, email, imageUrl) {
firebase.database().ref('users/' + userId).set({
username: name,
email: email,
profile_picture : imageUrl,
cropdata : []
});
}
I just found the solution, the asynchronous code wasn't waiting for my firebase response and just checeked if datapresent was true or not, so with a async definition before function and await before ref.once(value) does the trick and my problem is solve. Working code below :
const signInBtn = document.getElementById('signinbtn');
const signOutBtn = document.getElementById('signoutbtn');
const userDetails = document.getElementById('username');
var database = firebase.database();
const auth = firebase.auth();
const provider = new firebase.auth.GoogleAuthProvider();
signInBtn.onclick = () => auth.signInWithPopup(provider);
signOutBtn.onclick = () => auth.signOut();
async function checkdata(user){
let ref = firebase.database().ref("users");
let snapshot = await ref.once('value');
if (!snapshot.hasChild(user.uid)){
console.log(user)
writeUserData(user.uid,user.displayName,user.email,user.photoURL)
console.log("write done")
}
else{
console.log("did not write")
}
}
function writeUserData(userId, name, email, imageUrl) {
firebase.database().ref('users/' + userId).set({
username: name,
email: email,
profile_picture: imageUrl,
cropdata: []
});
}
function toggle(className, displayState) {
var elements = document.getElementsByClassName(className)
for (var i = 0; i < elements.length; i++) {
elements[i].style.display = displayState;
}
}
auth.onAuthStateChanged(function (user) {
if (user) {
// signed in
toggle('userishere', 'block');
toggle('usernothere', 'none');
//userDetails.innerHTML = `<h3>Hello ${user.displayName}!</h3> <p>User ID: ${user.uid}</p>`;
userDetails.innerHTML = `Hello ${user.displayName}!`
console.log(user)
checkdata(user)
}
else {
toggle('userishere', 'none');
toggle('usernothere', 'block');
userDetails.innerHTML = '';
}
})

how to stop duplication in firebase database

I want to authentication in my chat app so when user signedin one time so the data will insert on firbase database but when user just refresh his chrome so one another same data will added again so i want to stop duplication if user already inserted so i tried this code mentioned below but this is not working.
function onStateChanged(user) {
if (user) {
//alert(firebase.auth().currentUser.email + '\n' + firebase.auth().currentUser.displayName);
var userProfile = { email: '', name: '', photoURL: '' };
userProfile.email = firebase.auth().currentUser.email;
userProfile.name = firebase.auth().currentUser.displayName;
userProfile.photoURL = firebase.auth().currentUser.photoURL;
var db = firebase.database().ref('users');
var flag = false;
db.on('value', function (users) {
users.forEach(function (data) {
var user = data.val();
if (user.email === userProfile.email) {
flag = true;
}
});
if (flag === false) {
firebase.database().ref('users').push(userProfile, callback);
}
else {
document.getElementById('imgProfile').src = firebase.auth().currentUser.photoURL;
console.log('elsepart')
document.getElementById('imgProfile').title = firebase.auth().currentUser.displayName;
document.getElementById('lnkSignIn').style = 'display:none';
document.getElementById('lnkSignOut').style = '';
}
});
}
else{
document.getElementById('imgProfile').src = image/profile-image.png;
document.getElementById('imgProfile').title = '';
document.getElementById('linkSignIn').style = '';
document.getElementById('linkSignOut').style = 'display: none';
}
}
let callback = (error)=>{
if(error){
alert(error)
}
else{
document.getElementById('imgProfile').src = firebase.auth().currentUser.photoURL;
document.getElementById('imgProfile').title = firebase.auth().currentUser.displayName;
document.getElementById('linkSignIn').style = 'display: none';
document.getElementById('linkSignOut').style = '';
}
}
///////////
onFirebaseStateChanged();
you can try firebase read and write functions to do this, for reference: link
I have done something kind of similar. Here, I have checked my db for same entries, if that doesn't exist, only then it'll allow you to register.
firebase.database().ref('/login/' + username).once('value').then(function (snapshot) {
if (snapshot.val() === null || snapshot.val() === undefined) {
firebase.database().ref('login/' + username).set({
name: name,
email: username,
password: password
});
_this.setState({
showAlert: true,
alertMessage: "User has been successfully register. Please login",
alertType: 'success'
})
} else {
console.log("in true")
_this.setState({
showAlert: true,
alertMessage: "User already exist",
alertType: 'warning'
})
}
Also, for remaining in the same logged in state even after refresh, creating session storage seems like an easy solution to me.

Getting data from function

I am having some trouble getting the logged in status from the below function.
I can set the loggedIn status with currentUser.setProfile(username, token), which works.
But when i then try to get the isLoggedIn afterwards, i can't seem to get it.
console.log(currentUser) return the 2 functions, setProfile and getProfile. But getProfile is just an empty function.
I have tried currentUser.getProfile.isLoggedIn among others, but they all just return undefined.
What am i doing wrong?
Function:
(function () {
"use strict";
angular
.module("myApp")
.factory("currentUser",
currentUser)
function currentUser() {
var profile = {
isLoggedIn: false,
username: "",
token: ""
};
var setProfile = function (username, token) {
profile.username = username;
profile.token = token;
profile.isLoggedIn = true;
};
var getProfile = function () {
return profile;
}
return {
setProfile: setProfile,
getProfile: getProfile
}
}
})();
Because getProfile is a function, you should call it like
currentUser.getProfile().isLoggedIn

Firebase push don't work inside value event

I have code like this:
var firebase = new Firebase('https://<MY_APP>.firebaseio.com');
var users = firebase.child('users');
var usersDefer = $.Deferred();
var userName;
if (window.localStorage) {
userName = localStorage.getItem('username');
if (!userName) {
function newUser(users) {
if (userName) return;
var newUserName = prompt('Enter Username:');
if (users.indexOf(newUserName) !== -1) {
alert('Username already taken');
newUser(users);
} else {
localStorage.setItem('username', newUserName);
userName = newUserName;
console.log('push');
// this push don't work
users.push({
name: newUserName
});
console.log('after');
}
}
usersDefer.then(newUser);
}
}
users.once('value', function(snapshot) {
var value = snapshot.val()
if (value) {
var users = Object.values(value).map(function(object) {
return object.name;
});
usersDefer.resolve(users);
} else {
usersDefer.resolve([]);
}
});
and
users.push({
name: newUserName
});
don't work unless I use developer console, anybody have a clue why?
UPDATE:
Same happen if I use this code without jQuery Deferred
users.once('value', function(snapshot) {
function newUser(users) {
if (userName) return;
var newUserName = prompt('Enter your username');
if (users.indexOf(newUserName) !== -1) {
alert('Username already taken');
newUser(users);
} else {
userName = newUserName;
if (window.localStorage) {
localStorage.setItem('username', newUserName);
}
console.log('push');
users.push({
name: userName
});
console.log('after');
}
}
var value = snapshot.val()
var users;
if (value) {
users = Object.values(value).map(function(object) {
return object.name;
});
} else {
users = [];
}
if (window.localStorage) {
userName = localStorage.getItem('username');
if (!userName) {
newUser(users);
}
} else {
newUser(users);
}
});
The problem was that I was using same variable users for firebase reference and list of users.

How to Implement $child method in new AngularFire v0.8.0?

A user is logged in to the website and tries to create a post. Whenever a new post is created, this post gets associated with the user who created the post.
Referring to a thinkster.io Tutorial, which uses older API of AngularFire.
When using AngularFire API v0.8.0, this line of code which adds the post breaks:
user.$child('posts').$child(postId).$set(postId);
The Post Factory (post.js) with the method for creating post is:
app.factory('Post',
function ($firebase, FIREBASE_URL, User) {
var ref = new Firebase(FIREBASE_URL + 'posts');
var posts = $firebase(ref).$asArray();
var Post = {
all: posts,
//Starting of create function
create: function (post) {
if (User.signedIn()) {
var user = User.getCurrent(); //Gets the current logged in user
post.owner = user.username;
return posts.$add(post).then(function (ref) {
var postId = ref.name();
user.$child('posts').$child(postId).$set(postId);
//user.$getRecord('posts').$getRecord(postId).$set(postId);
return postId;
});
}
},
//End of create function
Changelog for AngularFire states that
$child() no longer exists. The data already exists in the parent object and creating additional synchronized children is not efficient and discouraged. Use data transformations, flatten your data, or drop down to the Firebase SDK and use its child() method.
I am confused as to how to change the code to work with the update in the API.
After Edit
This is the getCurrent method:
getCurrent: function(){ // retrieves current user
return $rootScope.currentUser;
},
Which belongs to user.js Factory:
'use strict';
app.factory('User', function ($firebase, FIREBASE_URL, Auth, $rootScope) {
var ref = new Firebase(FIREBASE_URL + 'users');
var users = $firebase(ref);
var usersdiv = $firebase(ref).$asArray();
var User = {
create: function (authUser, username) {
users[username] = {
md5_hash: authUser.md5_hash,
username: username
};
users.$update(username, {
md5_hash: authUser.md5_hash,
username: username
}).then(function (dataRef) {
dataRef.setPriority(authUser.uid);
setCurrentUser(username);
});
}, // end of create method
findByUsername: function(username){
if(username){
return usersdiv.$getRecord(username);
}
},
getCurrent: function(){ // retrieves current user
return $rootScope.currentUser;
},
signedIn: function(){ //checks if user is signed in
return $rootScope.currentUser !== undefined;
}
}; // end of User
// so that we can pull info about user when logged in
function setCurrentUser (username){
$rootScope.currentUser = User.findByUsername(username);
}
//for logins and refreshes
$rootScope.$on('$firebaseSimpleLogin:login', function(e, authUser){
var queryRef = ref.startAt(authUser.uid).endAt(authUser.uid);
var queryArray = $firebase(queryRef).$asArray();
queryArray.$loaded().then(function() {
setCurrentUser(queryArray.$keyAt(0));
});
});
//logout
$rootScope.$on('$firebaseSimpleLogin:logout', function(){
delete $rootScope.currentUser;
});
return User;
});
You don't need to create a synchronized object locally (what $child used to do) just to set a value in Firebase. You can do this at any time with the Firebase ref you've already created. I can't tell exactly what the data structure of user is since it wasn't included, but something like this:
new Firebase(FIREBASE_URL).child('...path/to/posts').child(postId).set(postId);
Most likely, this belongs on your user object, so that in the Post factory, you can just do something like user.addPost(postId).
I was facing the same problem. As Kato suggested, you will have to use the child function in the Firebase object. I chose to add the post to the user in the Post factory itself.
Adding Post to User
var usersref = new Firebase(FIREBASE_URL + 'users');
usersref.child(post.owner).child('posts').child(postId).set(postId);
The Entire post.js is as below:
'use strict';
app.factory('Post',
function($firebase, FIREBASE_URL, User){
var ref = new Firebase(FIREBASE_URL + 'posts');
var usersref = new Firebase(FIREBASE_URL + 'users');
var posts = $firebase(ref).$asArray();
var Post = {
all : posts,
create : function(post){
if(User.signedIn()){
var user = User.getCurrent();
post.owner = user.username;
return posts.$add(post).then(function(ref){
var postId = ref.name();
usersref.child(post.owner).child('posts').child(postId).set(postId);
return postId;
});
}
},
find: function(postId){
return $firebase(ref.child(postId)).$asObject();
},
delete: function(postId){
if(User.signedIn()){
var postToDel = Post.find(postId);
postToDel.$loaded().then(function(){
var p = posts[postToDel.$id];
posts.$remove(postId).then(function(){
$firebase(usersref.child(p.owner).child('posts')).$asArray().$remove(p.$id);
});
});
}
}
};
return Post;
});
Correct Answer is:
'use strict';
app.factory('Post',
function ($firebase, FIREBASE_URL, User) {
var postsref = new Firebase(FIREBASE_URL + 'posts');
var usersref = new Firebase(FIREBASE_URL + 'users');
var posts = $firebase(postsref).$asArray();
var Post = {
all: posts,
create: function (post) {
if (User.signedIn()) {
var user = User.getCurrent();
post.owner = user.username;
return posts.$add(post).then(function (ref) {
var postId = ref.name();
//a child in user forge should be made with its key as postID
usersref.child(post.owner).child('posts').child(postId).set(postId);
return postId;
});
}
},
find: function (postId) {
return $firebase(postsref.child(postId)).$asObject();
},
delete: function (postId) {
if (User.signedIn()) {
var postToDel = Post.find(postId);
postToDel.$loaded().then(function(){
var p = posts[postToDel.$id];
posts.$remove(postId).then(function(){
$firebase(usersref.child(p.owner).child('posts')).$remove(p.$id);
});
});
}
},
Thus, child can be used at Firebase SDK Level.
Example:
var ref = new Firebase(FIREBASE_URL);
var userArray = $firebase(ref.child('user')).$asArray();
var userObject = $firebase(ref.child('user')).$asObject();

Categories

Resources