rgins16 rgins16 - 6 months ago 27
AngularJS Question

AngularJS passing data between controllers

I have spent hours trying to figure out how to pass data between controllers. Can someone please help me out?

This is the entirety if my angularjs file:

var app = angular.module('FitnessApp', []);

var HTTP_RESPONSE = function(response) { return response.data || response; };
var HTTP_ERROR = function(err) {return err; };

app.service('Share', ['$rootScope', '$timeout', function($rootScope, $timeout) {
var user = null;
var viewUser = null;
return {
setUser: function(newUser) {user = newUser; return $rootScope.$broadcast('user:updated'); },
getUser: function() {return user;},

setSearchedUser: function(searchedUser) {
viewUser = searchedUser; console.log(viewUser);

$timeout(function(){
return $rootScope.$broadcast('user:searched');
}, 5000);

//return $rootScope.$broadcast('user:searched');
},
getSearchedUser: function() {return viewUser;}
};
}]);

app.service('UserFactory', ['$http', function($http){
return {
// checkUserExists: function(user) {
// return $http.get('/user/exists', user).then(HTTP_RESPONSE, HTTP_ERROR);
// },
/*updateRating: function(id, rating) {
return $http.put('/user/updateRating', {_id: id, rating: rating}).then(HTTP_RESPONSE, HTTP_ERROR);
},*/
userLogIn: function(user) {
return $http.post('/user/login', user).then(HTTP_RESPONSE, HTTP_ERROR);
},
getUser: function(user_id) {
return $http.get('/user/userProfile/' + user_id).then(HTTP_RESPONSE, HTTP_ERROR);
},
userSignup: function(user) {
return $http.post('/user/adduser', user).then(HTTP_RESPONSE, HTTP_ERROR);
},
userEdit: function(user) {
return $http.put('/user/updateUser', user).then(HTTP_RESPONSE, HTTP_ERROR);
},
userChangeEmail: function(user) {
return $http.put('/user/changeEmail', user).then(HTTP_RESPONSE, HTTP_ERROR);
},
userChangePassword: function(user) {
return $http.put('/user/changePassword', user).then(HTTP_RESPONSE, HTTP_ERROR);
},
userDelete: function(del) {
return $http.put('/user/deleteUser/', del).then(HTTP_RESPONSE, HTTP_ERROR);
},
/*trainerLogin: function(trainer) {
return $http.post('/trainer/login', trainer).then(HTTP_RESPONSE, HTTP_ERROR);
},*/
trainerSignup: function(trainer) {
return $http.post('/trainer/addTrainer', trainer).then(HTTP_RESPONSE, HTTP_ERROR);
},


findUser: function(email) {
return $http.get('/user/findByEmail/' + email).then(HTTP_RESPONSE, HTTP_ERROR);
},
updateRating: function(idUser, idViewed, rating) {
return $http.put('/user/updateRating', {_id_user: idUser, _id_viewed: idViewed, rating: rating}).then(HTTP_RESPONSE, HTTP_ERROR);
},
getRating: function(idUser, idViewed) {
return $http.put('/user/getRating', {_id_user: idUser, _id_viewed: idViewed}).then(HTTP_RESPONSE, HTTP_ERROR);
}

};
}]);


// service that contains the ajax query
app.service('TrainerFactory', ['$http', function($http) {
return {
trainerAddEvent: function(trainerEvent) {
return $http.post('/trainer/addEvent', trainerEvent).then(HTTP_RESPONSE, HTTP_ERROR);

}
};
}]);

// controller which injects the above service
app.controller('EventController', ['$scope', 'TrainerFactory', 'Share', function($scope, TrainerFactory, Share) {
$scope.trainerAddEvent = function(newEvent) {
TrainerFactory.trainerAddEvent(newEvent).then(function(response) {

window.location.replace('/');

}, function(err) {}).finally(function() {});
};
}]);


app.controller('RootController', ['$scope', '$window', 'UserFactory', 'Share', function($scope, $window, UserFactory, Share) {

$scope.initUser = function(user_id) {
UserFactory.getUser(user_id).then(function(response) {
Share.setUser(response);
}, function(err) {
console.log(err);
}).finally(function(){});
};

$scope.$on('user:updated', function(data) {
$scope.user = Share.getUser();
});

$scope.findUser = function(email) {
UserFactory.findUser(email).then(function(response) {

switch(response.status) {
case 200:

Share.setSearchedUser(response.data);

// gets the user object from users.js '/user/findByEmail/:email'
// $scope.viewUser = response.data;

// $scope.showme = true;

// // gets the user's average rating
// $scope.userAverage = response.data.rating;

//********************************************************************* this will need to change when we go live
$window.location.href = "http://10.0.0.25:8001/user/profile/";

break;
case 404:
// User not found
$scope.login_err = 'Email not found, please try again';
break;
default:
$scope.login_err = 'An unexpected Error has occurred, please try again later.';
}

}, function(err) {

}).finally(function(){});
};

}]);

app.controller('ViewProfileController', ['$scope', 'UserFactory', 'Share', function($scope, SearchFactory, Share) {

$scope.viewUser = Share.getSearchedUser(); console.log($scope.viewUser);

// gets the current user
$scope.$on('user:updated', function(data) {
$scope.user = Share.getUser();
});

$scope.$on('user:searched', function(data) {console.log('here');
$scope.viewUser = Share.getSearchedUser(); console.log($scope.viewUser);
});

$scope.updateRating = function(idUser, idViewed, rating) {
UserFactory.updateRating(idUser, idViewed, rating).then(function(response) {

// update rating for front end
$scope.userAverage = response.data;

}, function(err) {

}).finally(function() {});
};

$scope.getRating = function(idUser, idViewed) {
UserFactory.getRating(idUser, idViewed).then(function(response) {

// relay the current user's rating of the user being viewed
console.log(response.data);
$scope.rating = response.data;

}, function(err) {

}).finally(function() {});
};

}]);

app.controller('SignupController', ['$scope', 'UserFactory', 'Share', function($scope, UserFactory, Share) {
$scope.sayHello = function() {
console.log('hello!');
};

$scope.$on('user:updated', function(data) {
$scope.user = Share.getUser();
});

$scope.clearMessages = function(messages) {
messages.forEach(function(message) {
message = null;
});
};
// Login
$scope.userLogin = function(user) {
UserFactory.userLogIn(user).then(function(response) {
switch(response.status) {
case 200:
// Okay to proceed
window.location.replace('/');
break;
case 406:
// Okay to proceed
window.location.replace('/newTrainer');
break;
case 404:
// User not found
$scope.login_err = 'Email not found, please try again';
break;
case 401:
// Password incorrect
$scope.login_err = 'Incorrect password, please try again';
break;
case 400:
// Invalid request
break;
default:
$scope.login_err = 'An unexpected Error has occurred, please try again later.';
}
}, function(err) {}).finally(function() {
});
};

// Signup
$scope.userSignup = function(user) {
UserFactory.userSignup(user).then(function(response) {
switch(response.status) {
case 200:
// Okay to proceed
window.location.replace('/');
break;
case 401:
// User already exists
$scope.signup_err = 'Email unavailable or invalid, please try again';
return;
case 400:
// Invalid Request
$scope.signup_err = 'An Error has occurred, please contact support@smb.com for help.';
break;
default:
$scope.signup_err = 'An unexpected Error has occurred, please try again later';
}
}, function(err) {}).finally(function() {});
};

$scope.trainerSignup = function(newTrainer) {
UserFactory.trainerSignup(newTrainer).then(function(response) {
switch(response.status) {
case 200:
// Okay to proceed
window.location.replace('/newTrainer');
break;
case 401:
// User already exists
$scope.signup_err = 'Email unavailable or invalid, please try again';
return;
case 400:
// Invalid Request
$scope.signup_err = 'An Error has occurred, please contact support@smb.com for help.';
break;
default:
$scope.signup_err = 'An unexpected Error has occurred, please try again later';
}
}, function(err) {}).finally(function() {});
};
}]);

app.controller('ProfileController', ['UserFactory', 'Share', '$scope', function(UserFactory, Share, $scope) {
$scope.$on('user:updated', function() {
$scope.user = Share.getUser();
});

/*$scope.updateRating = function(id, rating) {
return UserFactory.updateRating(id, rating).then(function(response) {
//$scope.user.rating.push(rating);
}, function(err) {

}).finally(function() {});
};*/

$scope.updateUser = function(updatedUser) {
return UserFactory.userEdit(updatedUser).then(function(response) {
$scope.message = 'Success!';
}, function(err) {

}).finally(function() {});
};
$scope.changeEmail = function(updatedUser) {
return UserFactory.userChangeEmail(updatedUser).then(function(response) {
}, function(err) {}).finally(function() {});
};

$scope.changePassword = function(updatedUser) {
return UserFactory.userChangePassword(updatedUser).then(function(response) {
}, function(err) {}).finally(function() {});
};

$scope.deleteUser = function(user) {
UserFactory.userDelete(user).then(function(response) {
switch(response.status) {
case 200:
window.location.replace('/user/signup');
break;
case 404:
$scope.del_err = 'Wrong Email, please try again';
break;
default:
$scope.del_err = 'An unexpected error occurred, please try again later';
}
}, function(err) {}).finally(function() {
console.error(err);
});
};
}]);

app.service('ActivityService', ['$http', function($http) {
return {
addActivity: function(activity) {
return $http.put('/user/addActivity', {activity: activity}).then(HTTP_RESPONSE, HTTP_ERROR);
},
removeActivity: function(activity) {
return $http.put('/user/removeActivity', {activity: activity}).then(HTTP_RESPONSE, HTTP_ERROR);
},
hasInterest: function(activity, array) {
var found = false;
array.forEach(function(interest) {
found = found || activity === interest;
});
return found;
}
};
}]);

app.controller('ActivityController', ['$scope', 'Share', 'ActivityService', function($scope, Share, ActivityService) {
$scope.$on('user:updated', function() {
$scope.user = Share.getUser();
});

$scope.addActivity = function(activity) {
return ActivityService.addActivity(activity).then(function(response) {
$scope.user.activities.push(activity);
}, function(err) {

}).finally(function() {});
};
$scope.removeActivity = function(activity) {
return ActivityService.removeActivity(activity).then(function(response) {
console.log(response);
$scope.user.activities = $scope.user.activities.filter(function(act) {
console.log(act, activity);
return activity !== act;
});
}, function(err) {

}).finally(function() {});
};
$scope.hasInterest = function(interest) {
return ActivityService.hasInterest(interest, $scope.user.activities);
};

}]);

app.service('MapService', function() {
return {

};
});
app.controller('MapController', ['$scope', 'Share', 'MapService', function($scope, Share, MapService) {

}]);


I am trying to pass information about the user object from the RootController to the ViewProfile Controller.

I think a problem I may be having is that switching the view may be destroying the variable?

Can someone please point me in the right direction?

Here is layout.jade which uses RootController:

doctype html
html
head
title= title
link(rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css')
link(rel='stylesheet', href='/stylesheets/style.css')
link(rel='stylesheet' type='text/css' href='/stylesheets/jquery.datetimepicker.css')
link(rel='stylesheet' type='text/css' href='/stylesheets/ratings.css')

block loadfirst
script(src="https://code.jquery.com/jquery-1.12.3.min.js"
integrity="sha256-aaODHAgvwQW1bFOGXMeX+pC4PZIPsvn2h1sArYOhgXQ=" crossorigin="anonymous")
script(src='https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js')
script(src='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js')

script(src='/angular/fitnessapp.js')

body
div#wrapper(ng-app='FitnessApp')
div#header(ng-controller='RootController' ng-init='initUser(#{JSON.stringify(user)})')
nav.navbar.navbar-default
div.container-fluid
// Brand and toggle get grouped for better mobile display
div.navbar-header
button.navbar-toggle.collapsed(type='button', data-toggle='collapse', data-target='#bs-example-navbar-collapse-1', aria-expanded='false')
span.sr-only Toggle navigation
span.icon-bar
span.icon-bar
span.icon-bar
a.navbar-brand(href='/') SpotMeBro
// Collect the nav links, forms, and other content for toggling
div#bs-example-navbar-collapse-1.collapse.navbar-collapse
ul.nav.navbar-nav
li.dropdown
a.dropdown-toggle(href='#', data-toggle='dropdown', role='button', aria-haspopup='true', aria-expanded='false')
| Dropdown
span.caret
ul.dropdown-menu
li
a(href='#') {{user.type}}
li
a(href='#') Another action
li
a(href='#') Something else here
li.divider(role='separator')
li
a(href='#') Separated link
li.divider(role='separator')
li
a(href='#') One more separated link
form.navbar-form.navbar-left(role='search')
.form-group
input.form-control(type='text', placeholder='Search for an event')
button.btn.btn-default(type='submit') Submit
ul.nav.navbar-nav.navbar-right
if(!user)
li
a(href='/user/signup') Login/Signup
li
a(href='/trainer/signup') Trainer Signup
else
li
a(href='/user/search/') Search
li
a(ng-if='user.type' href='/trainer/createEvent') Create Event
li
a(href='/user/profile/') Profile
li
a(href='/user/interests') Interests
li
a(href='/user/settings') Settings
li
a(href='/logout') Logout

div
form.navbar-form.navbar-right(name='search' ng-submit="search.$valid && findUser(email);" novalidate)

div.form-group
div.input-group
input#email.form-control(name='email' ng-model='email' type='email' required)
button.btn.btn-default(type='submit') Search

div(ng-show='search.$submitted')
span.text-danger(ng-show='search.email.$error.required')
| Please enter an email.
span.text-danger(ng-show='search.email.$error.email')
| Please enter an email.



// /.navbar-collapse
// /.container-fluid
div#body
block content

div#footer
div.container-fluid.text-center
span.text-center Fütr
block scripts


And here is userProfile.jade which uses ViewProfileController:

extends layout

block content
div.container(ng-controller='ViewProfileController')
//- legend Search for user by email
//- form(name='search' ng-submit='search.$valid && findUser(email)' novalidate)

//- div.form-group
//- div.input-group
//- label(for='Email') Email
//- input#email.form-control(name='email' ng-model='email' type='email' required)

//- div(ng-show='search.$submitted || search.email.$touched')
//- span.text-danger(ng-show='search.email.$error.required')
//- | Please enter an email.
//- span.text-danger(ng-show='search.email.$error.email')
//- | Please enter an email.

//- div.form-group
//- button.btn.btn-primary(type='submit') Search

div
legend {{viewUser.firstName}} {{viewUser.lastName}}'s Profile {{user.email}} {{viewUser.email}}

div
span Email: {{viewUser.email}}
br
span Join Date: {{viewUser.joinDate}}

div
//img(src= "http://img.ifcdn.com/images/8c70c2b66b7a52154bb3d3faadf03995c2c1e5ca0144a8979c834e61a1e166f5_1.jpg" width="250" height="250")
img(src= "http://us.123rf.com/450wm/arcady31/arcady311212/arcady31121200002/16708573-anonymous-vector-sign.jpg" width="250" height="250")

div(ng-if='showme===true')
div(ng-init='getRating(user._id, viewUser._id)')

div#star-div {{viewUser.firstName}}'s average rating: {{userAverage}}
br
div(ng-if='user.email != viewUser.email')
span.star-rating
input(ng-change='updateRating(user._id, viewUser._id, rating);' ng-model='rating' type='radio', name='rate', value='1')
i
input(ng-change='updateRating(user._id, viewUser._id, rating);' ng-model='rating' type='radio', name='rate', value='2')
i
input(ng-change='updateRating(user._id, viewUser._id, rating);' ng-model='rating' type='radio', name='rate', value='3')
i
input(ng-change='updateRating(user._id, viewUser._id, rating);' ng-model='rating' type='radio', name='rate', value='4')
i
input(ng-change='updateRating(user._id, viewUser._id, rating);' ng-model='rating' type='radio', name='rate', value='5')
i
br

div Interests
br
label.label.label-default {{viewUser.activities}}
br

div Member Since
br
label.label.label-default {{viewUser.joinDate}}
br

div About Me
br
label.label.label-default {{viewUser.about}}
br

div RSVP'D Activities
br
label.label.label-default {{viewUser.upcomingActivities}}
br

div Past Activities
br
label.label.label-default {{viewUser.pastActivities}}
br

Answer

With your current navigation every time you navigate to a page the HTML sent back from the server will include everything from layout.jade.

Since this contains ng-app your application will restart and everything will be reset, including the variables in your service.

I recommend that you look into ngRoute instead for navigation.