MEAN stack pass parameter within router - angularjs

I'm a newbie to MEAN stack development. Trying to follow this tutorial https://thinkster.io/mean-stack-tutorial/ to get a simple web app working. I posted my code in the following. I created a middle layer parameter called post (see router.js file) to get a particular post. In my postCtrl, I want to pass the post/postId to the factory and get the particular post.
//$scope.post = postFactory.getById(id);
According to the tutorial, the post should be detected automatically from URL route. So I wonder how should I utilize it to get the post I want? Thanks for your time in advance
AngularController.js
var app = angular.module("littleStar" , ["service", "ui.router"]);
app.config([
'$stateProvider',
'$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
templateUrl: "/home.html",
controller: 'mainCtrl'
})
.state('post', {
url:'/post/{id}',
templateUrl: '/post.html',
controller:'postCtrl'
});
$urlRouterProvider.otherwise('home');
}]);
app.controller("mainCtrl", ["$scope", "$http", "postFactory", function ($scope, $http, postFactory) {
postFactory.get().success(function(data){
$scope.posts = data;
});
$scope.addPost = function() {
var title = $scope.title;
var link = $scope.link;
if (!title || title === "" || !link || link === "") {
return;
}
var newPost = {
"title": title,
"link": link
}
postFactory.create(newPost)
.success(function (data) {
postFactory.get().success(function(allPosts){
$scope.posts = allPosts;
});
});
$scope.title = "";
$scope.link = "";
};
$scope.incrementPost = function(post){
post.upvotes += 1;
};
}]);
app.controller("postCtrl", ["$scope", '$stateParams', "postFactory", function($scope, $stateParams, postFactory){
//$scope.post = postFactory.get($stateParams.id);
//$scope.post = postFactory.getById($stateParams.id);
$scope.addComment = function(){
var currentComments = postFactory.post[$stateParams.id].comments;
currentComments.push({
author:$scope.author,
body: $scope.body,
upvotes: 0
});
$scope.body = "";
}
$scope.incrementComment = function(comment){
comment.upvotes += 1;
}
}]);
router.get('/posts/:post', function(req, res) {
res.json(req.post);
});
router.param('post', function(req, res, next, id) {
var query = Post.findById(id);
query.exec(function (err, post){
if (err) { return next(err); }
if (!post) { return next(new Error('can\'t find post')); }
console(id);
req.post = post;
return next();
});
});
angularService.js
var service = angular.module("service", []);
service.factory("postFactory", ["$http", function($http){
return {
get : function(){
return $http.get("/posts");
},
create: function(newPost){
return $http.post("/post", newPost);
},
delete : function(id){
return $http.delete("/post/" + id);
},
getById : function(id){
return $http.get("posts/" + id);
}
}
}]);

You should be able to make the get post route in the following way:
router.get('/posts/:post', function(req, res) {
var query = Post.findById(req.params.post);
query.exec(function (err, post){
res.json(post);
});
});

Related

AngularJS $routeProvider Resolve Method Not Working

In my code, I define the following two routes:
$routeProvider.when('/problem/report', {
templateUrl: '/app/management/problem/reportAProblem.html',
controller: 'reportAProblemCtrl',
resolve: {
authorized: function($http, $location) {
var path = $location.path();
return $http.get('/svc/authorize/view?urlPath=' + path).then(function(response) {
var data = response.data;
if (response.data.result === 'NOT_AUTHORIZED') {
throw "NOT_AUTHORIZED";
}
return data;
})
}
}
});
$routeProvider.when('/problem', {
templateUrl: '/app/management/problem/problem.tmpl.html',
controller: 'problemCtrl',
resolve: {
authorized: ['$authorization', function($authorization) {
$authorization.authorize();
}]
}
});
The first case seems to work. However, the second case has had the function refactored into a Service, and AngularJS does not seem to be waiting for the Promise to resolve before displaying the page.
The refactored code looks like the following:
angular.module('authorization', [])
.factory('$authorization', ['$http', '$location',function($http, $location) {
var $authorization = {};
$authorization.authorize = function() {
var path = $location.path();
return $http.get('/svc/authorize/view?urlPath=' + path).then(function(response) {
var data = response.data;
if (response.data.result === 'NOT_AUTHORIZED') {
throw "NOT_AUTHORIZED";
}
return data;
});
}
return $authorization;
}]);
Can anyone tell me why the second case above doesn't wait for the promise to resolve before displaying the page?
Add return:
authorized: ['$authorization', function($authorization) { **return** $authorization.authorize(); }]

AngularJS retrieve data from backend using factory/service

I'm approaching AngularJS and I want to get data from a database. I succeeded in doing this
angular.module("myApp")
.controller("listaUtentiCtrl", function($scope, $http) {
$http.get("backListaUtenti.php").success(function(data) { $scope.utenti=data } )
});
but I'd like to use a factory / service in order use the data from multiple controllers (but is not working)
angular.module("myApp")
.factory("utentiService", function($http,$q) {
var self = $q.defer();
$http.get("backListaUtenti.php")
.success(function(data){
self.resolve(data);
})
.error(function(){
alert("Error retrieving data!");
})
return self.promise;
});
angular.module("myApp")
.controller("utenteCtrl", function($scope, $routeParams, utentiService, filterFilter) {
var userId = $routeParams.userId;
$scope.utente = filterFilter(utentiService.utenti, { id: userId })[0];
});
angular.module("myApp")
.controller("listaUtentiCtrl", function($scope, utentiService) {
$scope.utenti = utentiService.utenti;
});
Where am I failing?
The problem is in your service implementation. Here is your code refactored:
angular.module("myApp")
.factory("utentiService", function($http) {
return {
getData: function () {
return $http.get("backListaUtenti.php").then(function (response) {
return response.data;
});
}
};
});
angular.module("myApp")
.controller("utenteCtrl", function($scope, $routeParams, utentiService, filterFilter) {
var userId = $routeParams.userId;
utentiService.getData().then(function(data) {
$scope.utente = filterFilter(data, { id: userId })[0];
});
});
angular.module("myApp")
.controller("listaUtentiCtrl", function($scope, utentiService) {
utentiService.getData().then(function (data) {
$scope.utenti = data;
});
});
If your data is static you can cache the request and avoid unnecessary requests like this:
$http.get("backListaUtenti.php", { cache: true });

$window.location.href is undefined with angularjs

I programme an application in ASP.NET MVC6, angularjs and Bootstap.
I want reload a page after bootstrap modal closing.
To do this, I use $window.location.href but it's undefined.
This is my method in angular Controller:
angular
.module('LSapp')
.controller('CustomersCtrl', CustomersCtrl);
CustomersCtrl.$inject = ['$scope', '$http', '$location', '$modal', '$templateCache', '$window'];
function CustomersCtrl($scope, $http, $location, $modal, $window) {
$scope.edit = function(id)
{
var customer = getCustomer(id);
console.log('Customer => FirstName : ' + customer.FirstName);
var reqEditCustomer = $http({ url: '/api/customers/', dataType: 'json', method: 'PUT', data: JSON.stringify(customer), contentType: 'application/json; charset=utf-8' });
reqEditCustomer.success(function (dataResult) {
$scope.customer = dataResult;
$scope.cancel();
});
$scope.customers = getListCustomers();
$window.location.href = '/';
}
}
All runs except the redirection.
I hope someone can help me . Any help is welcome.
you can use
$location.path('/');
instead of
$window.location.href = '/';
Try This -
$location.path('/').replace();
if(!$scope.$$phase) $scope.$apply()
I tried to redirect since a view and not a modal. It's work.
So I think it's redirect with my modal who create problem.
It's my full controller:
(function () {
'use strict';
angular
.module('LSapp')
.controller('CustomersCtrl', CustomersCtrl)
.controller('CustomersGetCtrl', CustomersGetCtrl);
CustomersCtrl.$inject = ['$scope', '$http', '$location', '$modal', '$templateCache', '$window'];
function CustomersCtrl($scope, $http, $location, $modal, $window) {
/*---------------------------------------------------------------------------------
* Obtain Customer List
*--------------------------------------------------------------------------------*/
function getListCustomers()
{
var reqCustomers = $http.get('/api/Customers');
reqCustomers.success(function (dataResult) {
$scope.customers = dataResult;
});
return $scope.customers;
}
getListCustomers();
/*---------------------------------------------------------------------------------
* Obtain Customer by ID
*--------------------------------------------------------------------------------*/
function getCustomer(id) {
var reqGetCustomer = $http({ url: '/api/customers/' + id, method: 'GET' });
reqGetCustomer.success(function (dataResult) {
$scope.customer = dataResult;
})
return $scope.customer;
}
$scope.edit = function(id)
{
var customer = getCustomer(id);
console.log('Customer => FirstName : ' + customer.FirstName);
var reqEditCustomer = $http({ url: '/api/customers/', dataType: 'json', method: 'PUT', data: JSON.stringify(customer), contentType: 'application/json; charset=utf-8' });
reqEditCustomer.success(function (dataResult) {
$scope.customer = dataResult;
$scope.cancel();
});
$scope.customers = getListCustomers();
//This is that I tried to redirect
//$window.location.href = '/';
//$location.path('/').replace();
//if(!$scope.$phase) $scope.$apply
}
/*---------------------------------------------------------------------------------
* Manage Customer Details Modal
*--------------------------------------------------------------------------------*/
$scope.openDetails = function (id) {
var modalInstance = $modal.open({
templateUrl: 'Modals/Customers/details.html',
controller: $scope.modalDetails,
resolve: {
id: function () {
return id
}
}
});
}
$scope.modalDetails = function($scope, $modalInstance, id)
{
if (angular.isDefined(id)) {
var reqGetCustomer = $http({ url: '/api/Customers/' + id, method: 'GET' });
reqGetCustomer.success(function (dataResult) {
$scope.customer = dataResult;
});
} else { alert('id is undefined'); }
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
}
}
/*---------------------------------------------------------------------------------
* Manage Customer Edit Modal
*--------------------------------------------------------------------------------*/
$scope.openEdit = function (id) {
var modalInstance = $modal.open({
templateUrl: 'Modals/Customers/edit.html',
controller: $scope.modalEdit,
resolve: {
id: function () {
return id
}
}
});
}
$scope.modalEdit = function ($scope, $modalInstance, id) {
if (angular.isDefined(id)) {
var reqGetCustomer = $http({ url: '/api/Customers/' + id, method: 'GET' });
reqGetCustomer.success(function (dataResult) {
$scope.customer = dataResult;
});
} else { alert('id is undefined'); }
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
}
}
}
//Controller to redirect since View
CustomersGetCtrl.$inject = ['$scope', '$http', '$routeParams', '$window'];
function CustomersGetCtrl($scope, $http, $routeParams, $window)
{
function getCustomer()
{
var reqGetCustomer = $http({ url: '/api/customers/' + $routeParams.id, method: 'GET' })
reqGetCustomer.success(function (dataResult) {
$scope.customer = dataResult;
})
}
getCustomer();
$scope.edit = function () {
$window.location.href = '/';
}
}
})();
I solved the problem by using ui.router instead of ng -router.

Consume REST API with AngularJS

I'm trying to pull an object by its _id from the mongodb database and place it in the $scope for later use. However when I try to do so, I get every object in the database, instead of the one I requested. I'm new to the mean-stack and do not understand what I am doing wrong.
If you have any further question please let me know.
server.js
var express = require('express'),
app = module.exports = express(),
bodyParser = require('body-parser'),
mongoose = require('mongoose'),
productsController = require('./server/controllers/products-controller');
mongoose.connect('mongodb://localhost:27017/mean-demo');
app.use(bodyParser());
app.get('/', function (req, res) {
res.sendfile(__dirname + '/client/views/index.html');
});
app.get('/product/*', function (req, res) {
res.sendfile(__dirname + '/client/views/index.html');
});
app.use('/js', express.static(__dirname + '/client/js'));
app.use('/css', express.static(__dirname + '/client/css'));
app.use('/images', express.static(__dirname + '/client/images'));
app.use('/views', express.static(__dirname + '/client/views'));
//REST API
app.get('/api/products', productsController.products);
app.get('/api/products/:productId', productsController.product);
app.listen(3000, function() {
console.log('I\'m Listening...');
});
app.js
var app = angular.module('productApp', ['ngResource', 'ngRoute']);
app.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: '/views/productsoverview.html',
controller: 'productsController'
})
.when('/product/:productId', {
templateUrl: '/views/productFocus.html',
controller: 'productFocusController'
})
.otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(true)
}]);
app.controller('productsController', ['$scope', '$resource',
function($scope, $resource) {
var Product = $resource('/api/products');
$scope.products = [];
Product.query(function (results) {
$scope.products = results;
});
}]);
app.controller('productFocusController', ['$routeParams', '$scope', '$resource',
function($routeParams, $scope, $resource) {
var Product = $resource('/api/products/:productId',{productId:'#productId'});
Product.productId = $routeParams.productId;
console.log(Product.productId);
Product.query(function (result) {
console.log(result);
$scope.product = result;
});
}]);
productsController
var Product = require('../models/product');
exports.products = function (req, res) {
Product.find({}, function (err, results) {
res.json(results);
});
};
exports.product = function (req, res) {
Product.findOne({_id:req.params.productId}, function (err, obj) {
res.json(obj);
});
};
You are using ngResource a bit wrong.
Try to write a single resource, e.g.
app.resource('Product', ['$resource'
function($resource) {
return $resource('/api/products/:id', {id: '#id'},
{
'update': { method:'PUT' }
});
}]);
Now you can inject this resource into your controller:
app.controller('productsController', ['$scope', 'Product',
function($scope, Product) {
$scope.products = [];
// this gets ALL products (query)
Product.query(function (results) {
$scope.products = results;
});
// this gets ONE product by id (get)
Product.get({id: 123})
.$promise.then(function(product) {
$scope.product = product;
});
});
}]);
ngResource documentation

AngularJS Service Passing Data Between Controllers

When using an AngularJS service to try and pass data between two controllers, my second controller always receives undefined when trying to access data from the service. I am guessing this is because the first service does a $window.location.href and I'm thinking this is clearing out the data in the service? Is there a way for me to change the URL to a new location and keep the data persisted in the service for the second controller? When I run the code below the alert in the second controller is always undefined.
app.js (Where Service is Defined)
var app = angular.module('SetTrackerApp', ['$strap.directives', 'ngCookies']);
app.config(function ($routeProvider)
{
$routeProvider
.when('/app', {templateUrl: 'partials/addset.html', controller:'SetController'})
.when('/profile', {templateUrl: 'partials/profile.html', controller:'ProfileController'})
.otherwise({templateUrl: '/partials/addset.html', controller:'SetController'});
});
app.factory('userService', function() {
var userData = [
{yearSetCount: 0}
];
return {
user:function() {
return userData;
},
setEmail: function(email) {
userData.email = email;
},
getEmail: function() {
return userData.email;
},
setSetCount: function(setCount) {
userData.yearSetCount = setCount;
},
getSetCount: function() {
return userData.yearSetCount;
}
};
});
logincontroller.js: (Controller 1 which sets value in service)
app.controller('LoginController', function ($scope, $http, $window, userService) {
$scope.login = function() {
$http({
method : 'POST',
url : '/login',
data : $scope.user
}).success(function (data) {
userService.setEmail("foobar");
$window.location.href = '/app'
}).error(function(data) {
$scope.login.error = true;
$scope.error = data;
});
}
});
appcontroller.js (Second controller trying to read value from service)
app.controller('AppController', function($scope, $http, userService) {
$scope.init = function() {
alert("In init userId: " userService.getEmail());
}
});
Define your service like this
app.service('userService', function() {
this.userData = {yearSetCount: 0};
this.user = function() {
return this.userData;
};
this.setEmail = function(email) {
this.userData.email = email;
};
this.getEmail = function() {
return this.userData.email;
};
this.setSetCount = function(setCount) {
this.userData.yearSetCount = setCount;
};
this.getSetCount = function() {
return this.userData.yearSetCount;
};
});
Check out Duncan's answer here:
AngularJS - what are the major differences in the different ways to declare a service in angular?

Resources