I have an express server with passport-local stategy, passport-local and passport-local-mongoose also installed.I want to access current user model as json to read and write data into it. My headache is that object doesn't want to display the data inside my view. It's loading with no errors and I cannot understand what's happening. Please help me!
Here is my express config:
var express = require('express'),
app = express(),
morgan = require('morgan'),
bodyParser = require('body-parser'),
cookieParser = require('cookie-parser'),
expressSession = require('express-session'),
hash = require('bcrypt-nodejs'),
mongoose = require('mongoose'),
path = require('path'),
passport = require('passport'),
localStrategy = require('passport-local').Strategy,
port = process.env.PORT || 8080,
User = require('./app/models/user'),
routes = require('./app/routes/api');
mongoose.connect('mongodb://localhost:27017/dashboard');
app.use(express.static(__dirname + '/src'));
app.use(morgan('dev'));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use(cookieParser());
app.use(require('express-session')({
secret: 'keyboard kat',
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
passport.use(new localStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
app.use(function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET', 'POST');
res.header('Access-Control-Allow-Methods', 'X-Requested-With, content- type, Authorization');
next();
});
app.use('/user', routes);
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname + '/src/views', 'index.html'));
});
app.use(function (req, res, next) {
var err = new Error('not found :(');
err.status = 404;
next(err);
});
app.use(function (err, req, res) {
res.status(err.status || 500);
res.end(JSON.stringify({
message: err.message,
error: {}
}));
});
app.listen(port);
console.log('Magic happens on port ' + port);
And the route which I use to pull the data:
router.get('/data', function (req, res) {
res.send(req.user);
});
Сhrome dev tools returns correct object:
Angular service:
angular.module('main')
.factory('MenuService', function ($http) {
function getData() {
$http.get('/user/data')
.success(function (data) {
return data;
});
}
return {
info: getData
}
});
Controller:
angular.module('main')
.controller('menuController', function ($mdSidenav, MenuService) {
var vm = this;
vm.toggleMenu = function () {
$mdSidenav('menu').toggle();
};
vm.info = MenuService.info();
});
And finaly the view:
<md-toolbar layout="row" ng-controller="menuController as menu">
<div class="md-toolbar-tools">
<md-button class="md-icon-button md-primary" ng-click="menu.toggleMenu()" aria-label="open menu">
<md-icon md-svg-icon="../../assets/img/hmg.svg"></md-icon>
</md-button>
<h1>Dashboard</h1>
<span flex></span>
<h1>{{menu.info.name}}</h1>
</div>
</md-toolbar>
And nothing happens :( No view, no errors, absolutely nothing:
You need to return a promise when dealing with async calls or use pub-sub pattern for telling that your data arrived.
What is happening is that the getData
function gets called, in the background fetches the data, but it is not returned to the the caller of the getData
caller. Why? Because inside getData
nothing is returned. Something needs to be returned.
Here is a solution returning the promise.
Update : Sorry, sometimes I forgot that $http
returns a resp object, which has the data. Updated the code according to that.
So in your service :
angular.module('main')
.factory('MenuService', function ($http) {
function getData() {
return $http.get('/user/data'); //no preprocessing just returning the result of the http call
}
return {
info: getData
}
});
And in your controller
angular.module('main')
.controller('menuController', function ($mdSidenav, MenuService) {
var vm = this;
vm.toggleMenu = function () {
$mdSidenav('menu').toggle();
};
//todo this will be called whenever menuController gets initiated
//better to put into user action or run only one time...
MenuService.info().then(function(resp){
console.log(resp); //here is the response
vm.info = resp.data;
}, function(err){
//todo when no data arrived
});
return vm;
});
Also .success
and .error
are deprecated according to docs
The $http legacy promise methods success and error have been deprecated. Use the standard then method instead. If $httpProvider.useLegacyPromiseExtensions is set to false then these methods will throw $http/legacy error.