tharderer
tharderer

Reputation: 83

What is Ember.bind and how does it work?

Hi i have read the documentation and a couple of blog posts and i still don't understand what is happening with .bind(this) in the code below.

The code works for me but i hate not understanding what is going on

  1. What would happen if i deleted .bind(this) from the code below?
  2. What is getting bound to what?

    

import Ember from 'ember'; // Since I've defined my url in environment.js I can do this import ENV from '../config/environment'; var ref = new window.Firebase(ENV.firebase); export default { name: 'session', // Run the initializer after the store is ready after: 'store', initialize: function(container, app) { // session object is nested here as we need access to the container to get the store var session = Ember.Object.extend({ // initial state authed: false, init: function() { // get access to the ember data store this.store = container.lookup('store:main'); // on init try to login ref.onAuth(function(authData) { // Not authenticated if (!authData) { this.set('authed', false); this.set('authData', null); this.set('user', null); return false; } // Authenticated this.set('authed', true); this.set('authData', authData); this.afterAuthentication(authData.uid); ***}.bind(this));*** }, // Call this from your Ember templates login: function(provider) { this._loginWithPopup(provider); }, // Call this from your Ember templates logout: function() { ref.unauth(); }, // Default login method _loginWithPopup: function(provider) { var _this = this; // Ember.debug('logging in with popup'); ref.authWithOAuthPopup(provider, function(error, authData) { if (error) { if (error.code === "TRANSPORT_UNAVAILABLE") { // fall-back to browser redirects, and pick up the session // automatically when we come back to the origin page _this._loginWithRedirect(provider); } } else if (authData) { // we're good! // this will automatically call the on ref.onAuth method inside init() } }); }, // Alternative login with redirect (needed for Chrome on iOS) _loginWithRedirect: function(provider) { ref.authWithOAuthRedirect(provider, function(error, authData) { if (error) { } else if (authData) { // we're good! // this will automatically call the on ref.onAuth method inside init() } }); }, // Runs after authentication // It either sets a new or already exisiting user afterAuthentication: function(userId) { var _this = this; // See if the user exists using native Firebase because of EmberFire problem with "id already in use" ref.child('users').child(userId).once('value', function(snapshot) { var exists = (snapshot.val() !== null); userExistsCallback(userId, exists); }); // Do the right thing depending on whether the user exists function userExistsCallback(userId, exists) { if (exists) { _this.existingUser(userId); } else { _this.createUser(userId); } } }, // Existing user existingUser: function(userId) { var _this = this; this.store.find('user', userId).then(function(user) { _this.set('user', user); ***}.bind(this));*** }, // Create a new user createUser: function(userId) { var _this = this; this.get('store').createRecord('user', { id: userId, provider: this.get('authData.provider'), name: this.get('authData.facebook.displayName') || this.get('authData.google.displayName'), email: this.get('authData.facebook.email') || this.get('authData.google.email'), created: new Date().getTime() }).save().then(function(user){ // Proceed with the newly create user _this.set('user', user); }); }, // This is the last step in a successful authentication // Set the user (either new or existing) afterUser: function(user) { this.set('user', user); } }); // Register and inject the 'session' initializer into all controllers and routes app.register('session:main', session); app.inject('route', 'session', 'session:main'); app.inject('controller', 'session', 'session:main'); } }; <code>

Upvotes: 1

Views: 459

Answers (1)

jnfingerle
jnfingerle

Reputation: 713

You are using .bind(this) on a callback function. That means, that the this inside the function would normally refer to the context where the function is called (this is JavaScript, which is different from other languages regarding contexts). You want this to refer to the current context. And that's just what .bind(this) does: It ensures that the callback function will be called with the current context (instead of its default context).

Upvotes: 2

Related Questions