With the below code, I'm trying to show a toast with AngularJS inside a Firebase function. The function is showToast() but I'm getting a function not defined error. Any help would be appreciated, thanks!

Function:

app.controller('PageCtrl', function($scope, $mdToast, $document) {
  function showToast() {
    $mdToast.show(
      $mdToast.simple()
      .textContent('Simple lala Toast!')
      .hideDelay(3000)
    );
  };
});

Attempt to call function:

function signInUser(email, password) {
  var email = document.getElementById('email-input').value;
  var password = document.getElementById('password-input').value;

  auth.signInWithEmailAndPassword(email, password).then(function(value) {
    // REDIRECT TO THE HOME PAGE AFTER LOGIN
    //window.location = "#/home";
    //location.reload();

    showToast();

  }).catch(function(error) {
    var errorCode = error.code;
    var errorMessage = error.message;

    if (errorCode == 'auth/invalid-email') {
      alert('That user does not exist.');
    } else {
      alert(errorMessage);
    }
    console.log(error);
  });
}

Full Script:

/*

INITIALIZATION

*/

// FIREBASE CONFIGURATION
var config = {
  apiKey: "AIzaSyA2_fVDRCKhCJ5QueXY-Xb2CxFFuxY-rdU",
  authDomain: "user-database-d1a70.firebaseapp.com",
  databaseURL: "https://user-database-d1a70.firebaseio.com",
  storageBucket: "user-database-d1a70.appspot.com",
  messagingSenderId: "528331985076"
};

// INITIALIZE FIREBASE
firebase.initializeApp(config);
var database = firebase.database();
var auth = firebase.auth();

// ANGULARJS APPLICATION
var app = angular.module('FirebaseTest', [
  'ngRoute', 'ngMaterial', 'ngMessages'
]);

/*

ROUTES

*/

app.config(['$routeProvider', function ($routeProvider) {
  $routeProvider
  .when("/home", {templateUrl: "partials/home.html", controller: "PageCtrl"})
  .when("/about", {templateUrl: "partials/about.html", controller: "PageCtrl"})
  .when("/faq", {templateUrl: "partials/faq.html", controller: "PageCtrl"})
  .when("/nutrition", {templateUrl: "partials/nutrition.html", controller: "PageCtrl"})
  .when("/login", {templateUrl: "partials/login.html", controller: "PageCtrl"})
  .when("/register", {templateUrl: "partials/register.html", controller: "PageCtrl"})
  .otherwise({redirectTo:"/home", template: "partials/home.html", controller: "PageCtrl"});
}]);

/*

CONTROLLERS

*/

app.controller('PageCtrl', function($scope) {

});

app.controller('NavCtrl', function($scope) {
  var url = document.URL;
  var array = url.split('/');
  var pathname = array[array.length-1];

  console.log("Pathname: "+pathname);
  $scope.currentNavItem = pathname;
});

app.controller('NutritionCtrl', function($scope) {
  $scope.user = {
    gender: 'Female',
    goal: 'Lose Weight'
  };

  $scope.genders = ('Male Female').split(' ').map(function(gender) {
    return {abbrev: gender};
  });
  $scope.goals = ('Lose Weight_Gain Weight').split('_').map(function(goal) {
    return {abbrev: goal};
  });
});

app.controller('PageCtrl', function($scope, $mdToast, $document) {
  function showToast() {
    $mdToast.show(
      $mdToast.simple()
        .textContent('Simple lala Toast!')
        .hideDelay(3000)
    );
  };
});

/*

METHODS

*/

// FIREBASE CREATE USER METHOD
function writeUserData(email, password) {
  auth.createUserWithEmailAndPassword(email, password)
  .then(function () {

  })
  .catch(function(error) {
    var errorCode = error.code;
    var errorMessage = error.message;

    if (errorCode == 'auth/weak-password') {
      alert('The password is too weak.');
    } else {
      alert(errorMessage);
    }
    console.log(error);
  });
}

// FIREBASE SIGN IN USER METHOD
function signInUser(email, password) {
  var email = document.getElementById('email-input').value;
  var password = document.getElementById('password-input').value;

  auth.signInWithEmailAndPassword(email, password).then(function(value) {
    // REDIRECT TO THE HOME PAGE AFTER LOGIN
    //window.location = "#/home";
    //location.reload();

    showToast();

  }).catch(function(error) {
    var errorCode = error.code;
    var errorMessage = error.message;

    if (errorCode == 'auth/invalid-email') {
      alert('That user does not exist.');
    } else {
      alert(errorMessage);
    }
    console.log(error);
  });
}

// FIREBASE SIGN OUT USER METHID
function signOutUser() {
  auth.signOut().then(function() {
    // REDIRECT TO THE HOME PAGE AFTER LOGOUT
    window.location = "#/home";
    location.reload();
  }, function(error) {
    // Errors go here.
  });
}

// FIREBASE AUTH STATE CHANGE METHOD
auth.onAuthStateChanged(function(user) {
  // NAVIGATION LINKS
  var nutritionLink = document.getElementById('nav-nutrition');

  // USER INFORMATION
  var user = firebase.auth().currentUser;

  if (user) {
    email = user.email;
    uid = user.uid;

    // HIDE/SHOW LINKS
    $(nutritionLink).show();

    // UPDATE HEADER TEXT WITH USER EMAIL
    document.getElementById('header-username').innerHTML="Logged in as " + email + " - <a href='#' onclick='return signOutUser(this);'>Sign Out</a>";

    console.log("Provider-specific UID: "+uid);
    console.log("Email: "+email);
  } else {

    // HIDE/SHOW LINKS
    $(nutritionLink).hide();

    // UPDATE HEADER TEXT WITH USER EMAIL
    document.getElementById('header-username').innerHTML="<a href='#/login'>Login/Register</a>";
  }
});

/*

FUNCTIONS

*/
share
1  
Where is signInUser() declared? If it's not defined within PageCtrl, it will not be accessible. – Sam Dec 12 '16 at 20:03
1  
Your showToast function exists(and is only accessible) inside your PageCtrl controller which im assuming your signInUser function is not in. – Justin Dec 12 '16 at 20:04
    
@Justin That's correct. I didn't know a function inside a controller couldn't be accessible outside of that controller. Any ideas how to work around that? I also added my full script to the post. Thanks. – user2989388 Dec 12 '16 at 20:13
    
@Sam It's not within PageCtrl. I didn't know a function inside a controller couldn't be accessible outside of that controller. Any ideas how to work around that? I also added my full script to the post. Thanks. – user2989388 Dec 12 '16 at 20:14
1  
What a mess! Accessing the dom inside the controller! Should bind this email/password to the $scope – Fals Dec 12 '16 at 20:47

You could do it like this:

JS

app.controller('PageCtrl', function($scope, $mdToast, $document) {
  function showToast() {
    $mdToast.show(
      $mdToast.simple()
        .textContent('Simple lala Toast!')
        .hideDelay(3000)
    );
  };

  // FIREBASE SIGN IN USER METHOD
  $scope.signInUser = function () {
    var email = document.getElementById('email-input').value;
    var password = document.getElementById('password-input').value;

    auth.signInWithEmailAndPassword(email, password).then(function(value) {
      // REDIRECT TO THE HOME PAGE AFTER LOGIN
      //window.location = "#/home";
      //location.reload();

      showToast();

    }).catch(function(error) {
      var errorCode = error.code;
      var errorMessage = error.message;

      if (errorCode == 'auth/invalid-email') {
        alert('That user does not exist.');
      } else {
        alert(errorMessage);
      }
      console.log(error);
    });
  }
});

Markup

<buttton ng-click="signInUser()">Sign In</button>

You don't need to pass in email and password as you are getting them within the function.

Edit: You should rethink your whole approach as you aren't using AngularJS in the best way. For example do something like this:

<input type="email" ng-model="email">

and in your controller use $scope.email rather than

var email = document.getElementById('email-input').value;
share

First place the function onto the scope of the controller so it is accessible

app.controller('PageCtrl', function($scope, $mdToast, $document) {
    $scope.showToast = function () {
        $mdToast.show(
            $mdToast.simple()
            .textContent('Simple lala Toast!')
            .hideDelay(3000)
        );
    };
});

Then in your 'signInUser()' function call the controller using the following code, where '#pageCtrlID' is the id given to the controllers tag.

angular.element($('#pageCtrlID')).scope().showToast();

This is hackish and I highly recommend that you look into structuring your page to follow a more Angular design (ie no DOM manipulation) if you have the time.

share

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.