Consume REST API with AngularJS - 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

Related

Controller doesn't see function

This is my services.js
(function () {
var app = angular.module('crmService', []);
app.factory('timeline', ['$http', function ($http) {
var _addTimelineEvent = function (clientId, eventData) {
callback = callback || function () {};
return $http({
method: 'POST',
url: '/simple_crm/web/api.php/client/' + clientId + '/timeline',
data: eventData
});
};
return {
addTimelineEvent: _addTimelineEvent
};
}]);
})();
And this is my controller:
app.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
$routeProvider
.when('/clients', {
controller: 'ClientsListCtrl',
templateUrl: 'views/clients-list.html'
})
.when('/clients/:clientId', {
controller: 'ClientDetailCtrl',
templateUrl: 'views/client-details.html'
})
.otherwise({
redirectTo: '/clients'
});
$locationProvider.html5Mode(true).hashPrefix('');
}]);
app.controller('ClientDetailCtrl', ['$scope', 'clients', 'users', 'sectors', '$routeParams', '$timeout', 'timeline',
function ($scope, clients, users, sectors, $routeParams, $timeout, timeline) {
$scope.client = {};
$scope.timeline = [];
$scope.timelineEvent = {};
$scope.eventTypes = timeline.getEventsType();
$scope.saveClientData = function () {
if ($scope.clientForm.$invalid)
return;
clients.updateClient($scope.client.id, $scope.client)
.then(
function () {
//messeges to user
},
function (error) {
console.log(error);
}
);
};
$scope.addEvent = function () {
if ($scope.eventForm.$invalid)
return;
timeline.addTimelineEvent($scope.client.id, $scope.timelineEvent)
.then(
function () {
//messeges to user
},
function (error){
console.log(error);
});
};
}]);
})();
And I get an error:
TypeError timeline.addTimelineEvent is not a function
I am not able to understand why the function that is above works fine but timeline.addTimelineEvent, which is virtually identical, reports an error.
Any advice?
I added all code for better view :
Full code
The timeline function is located at the end of the app file

Error: $injector:modulerr Module Error in my browser

I'm new to AngularJS and I'm trying to run this AngularJS that should modify the URL without reloading the page but the console says Uncaught Error: [$injector:modulerr]
Where is the problem?
var app = angular.module("SearchAPP", ['ng-route']);
app.run(['$route', '$rootScope', '$location',
function($route, $rootScope, $location) {
var original = $location.path;
$location.path = function(path, reload) {
if (reload === false) {
var lastRoute = $route.current;
var un = $rootScope.$on('$locationChangeSuccess', function() {
$route.current = lastRoute;
un();
});
}
return original.apply($location, [path]);
};
}
]);
app.controller('GetController', ['$http', '$scope', '$location',
function($http, $scope, $rootScope, $location) {
$scope.click = function() {
var response = $http({
url: 'http://localhost:4567/search',
method: "GET",
params: {
keyword: $scope.searchKeyword
}
});
response.success(function(data, status, headers, config) {
$scope.searchResults1 = data;
// $http.defaults.useXDomain = true;
$location.path('/' + $scope.searchKeyword, false);
});
response.error(function(data, status, headers, config) {
alert("Error.");
});
};
}
]);
Attach angualar-route.js and use ngRoute instead of ng-route
var app = angular.module("SearchAPP", ['ngRoute']);

Why Unknown function "getJalse" in factory Angular JS

I am trying make an ajax request to php from angular js. But I am not getting the data I have sent by php file.
an error Unknown function "getJalse" exist in factory
My source:
File app.js:
(function () {
var app = angular.module('myApp', ['ngRoute']);
app.config(function ($routeProvider) {
$routeProvider
.when('/', {
controller: 'contentsCtrl',
templateUrl: 'views/contents.php'
})
.when('/jalse/:jalseId', {
controller: 'recordsCtrl',
templateUrl: 'views/jalse.php'
})
.otherwise({redirectTo: '/'});
});
}());
File jalseFactory.js:
(function () {
'use strict';
var jasleFactory = function ($http, $q) {
var factory = {};
factory.getJalses = function () {
var deferred = $q.defer();
$http({method: 'GET', url: 'includes/records.php'}).
success(function (data, status, headers, config) {
deferred.resolve(data);
}).
error(function (data, status, headers, config) {
deferred.reject(data);
});
return deferred.promise;
};
return factory;
};
jasleFactory.$inject = ['$http', '$q'];
angular.module('myApp').factory('jasleFactory', jasleFactory);
}());
File recordsCtrl.js:
(function () {
'use strict';
var recordsCtrl = function ($scope, $routeParams , jasleFactory) {
var jalseId = $routeParams.jalseId;
$scope.records = jasleFactory.getJalse();
$scope.jalse = null;
function init() {
for (var i = 0, len = $scope.records.length; i < len; i++) {
if ($scope.records[i].contentID == parseInt(jalseId)) {
$scope.jalse = $scope.records[i];
break;
}
}
}
init();
};
recordsCtrl.$inject = ['$scope' , '$routeParams' , 'jasleFactory'];
angular.module('myApp').controller('recordsCtrl', recordsCtrl);
}());
Because your factory has getJalses and you are calling getJalse.
Change
factory.getJalses = function ()
To
factory.getJalse = function ()

MEAN stack pass parameter within router

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);
});
});

Angularjs $on not firing after $rootScope.$broadcast

I have this code where two controllers are using a shared service to communicate.
var app = angular.module('AdminApp', ['ngRoute']);
app.factory('SharedService', function ($rootScope) {
var sharedService = {
userId: [],
BroadcastUserId: function (id) {
this.userId.push(id);
$rootScope.$broadcast('handleBroadcast');
}
};
return sharedService;
});
app.config(function ($routeProvider) {
$routeProvider.when('/login', {
templateUrl: "adminLogin.html"
});
$routeProvider.when('/main', {
templateUrl: 'adminMain.html'
});
$routeProvider.otherwise({
redirectTo: '/login'
});
});
app.controller('authCtrl', function ($scope, $http, $location, SharedService) {
$scope.Userid = '';
$scope.authenticate = function (user, pass) {
$http.post('http://localhost/NancyAPI/auth', {
UserName: user,
Password: pass
}).success(function (data) {
$scope.$broadcast('Token', data.Token);
$http.defaults.headers.common['Authorization'] = 'Token ' + data.Token;
$scope.Userid = data.UserId;
SharedService.BroadcastUserId($scope.Userid);
$location.path("/main");
}).error(function (response) {
$scope.authenticationError = response.error || response;
});
};
$scope.$on('handleBroadcast', function () {
console.log('on');
});
}).$inject = ['$scope', '$rootScope', 'SharedService'];
app.controller('mainCtrl', function ($scope, $http, $q, SharedService) {
$scope.tests = [];
$scope.userId = -1;
$scope.getTests = function () {
var deferred = $q.defer();
$http.get('http://localhost/NancyAPI/auth/tests/' + $scope.userId).
success(function (data) {
deferred.resolve(data);
$scope.tests = angular.fromJson(data);
}).error(function (response) {
});
};
// THIS IS NOT FIRING
$scope.$on('handleBroadcast', function () {
$scope.userId = SharedService.userId;
});
}).$inject = ['$scope', '$rootScope', 'SharedService'];
For some reason the $scope.$on is firing in the AuthCtrl controller but not in the mainCtrl.
// THIS IS NOT FIRING
$scope.$on('handleBroadcast', function () {
$scope.userId = SharedService.userId;
});
Why is this happening and how do I fix it?
I made a subtle mistake of not providing the {$rootScope} as dependency. Once I corrected that, it worked for me. I used Inline Array Annotation mechanism to achieve the same.

Resources