401 Unauthorized Response On Post - javascript

I've been making node.js website using angular template.
But I can't create data on DB(Mongo).
Here are code.
node routing.
var Property = mongoose.model('Property');
var jwt = require('express-jwt');
var auth = jwt({
secret: 'SECRET',
userProperty: 'payload'
});
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId; //Have also tried Schema.Types.ObjectId, mongoose.ObjectId
// Property Routing Management
router.post('/property', auth, function(req, res, next) {
var property = new Property(req.body);
console.log("checkpoint api");
property.save(function(err, property) {
if (err) {
return next(err);
}
return res.json(property);
})
});
AngularJS HTML
<form class="form-horizontal">
<label class="col-md-3 control-label" for="title">Member Name:</label>
<div class="col-md-5">
<input id="notific8_text" type="text" class="form-control" value="" placeholder="" ng-model="property.user">
</div>
<button ng-click="updateProperty()"> Submit </button>
</form>
AngularJS Controller.
angular.module('MainApp').controller('EditPropertyController', [
'$scope',
's_property',
's_auth',
'$state',
'$location',
function($scope, s_property, s_auth, $state, $location) {
$scope.updateProperty = function()
{
var data = {
user: $scope.property.user,
}
s_property.create(data);
};
}]);
and AngularJS service.
angular.module('MetronicApp')
.factory('s_property', [
'$http',
'$window',
's_auth',
function($http, $window, s_auth) {
var service = {
all_properties: [],
current_property: {}
};
service.create = function(property) {
console.log("checkpoint service");
return $http.post('/api/v1/property', property);
};
};
]);
When I input data in the input tag and click the submit button, chrome console shows like this
POST http://localhost:3000/property 401 (Unauthorized)
What is the mistake?
Cheers.
PS
this is
angular.module('MainApp')
.factory('s_auth', ['$http', '$window', function($http, $window){
var auth = {};
auth.saveToken = function (token) {
$window.localStorage['current-user-token'] = token;
};
auth.getToken = function() {
return $window.localStorage['current-user-token'];
};
}
service

Looks like you are not sending the JWT token to your backend.
TO be sending it try adding headers { authorization: "{TOKEN}"} in your post request

Related

MEAN Stack Can't list data on table [duplicate]

I've been making node.js website using angular template.
But I can't create data on DB(Mongo).
Here are code.
node routing.
var Property = mongoose.model('Property');
var jwt = require('express-jwt');
var auth = jwt({
secret: 'SECRET',
userProperty: 'payload'
});
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId; //Have also tried Schema.Types.ObjectId, mongoose.ObjectId
// Property Routing Management
router.post('/property', auth, function(req, res, next) {
var property = new Property(req.body);
console.log("checkpoint api");
property.save(function(err, property) {
if (err) {
return next(err);
}
return res.json(property);
})
});
AngularJS HTML
<form class="form-horizontal">
<label class="col-md-3 control-label" for="title">Member Name:</label>
<div class="col-md-5">
<input id="notific8_text" type="text" class="form-control" value="" placeholder="" ng-model="property.user">
</div>
<button ng-click="updateProperty()"> Submit </button>
</form>
AngularJS Controller.
angular.module('MainApp').controller('EditPropertyController', [
'$scope',
's_property',
's_auth',
'$state',
'$location',
function($scope, s_property, s_auth, $state, $location) {
$scope.updateProperty = function()
{
var data = {
user: $scope.property.user,
}
s_property.create(data);
};
}]);
and AngularJS service.
angular.module('MetronicApp')
.factory('s_property', [
'$http',
'$window',
's_auth',
function($http, $window, s_auth) {
var service = {
all_properties: [],
current_property: {}
};
service.create = function(property) {
console.log("checkpoint service");
return $http.post('/api/v1/property', property);
};
};
]);
When I input data in the input tag and click the submit button, chrome console shows like this
POST http://localhost:3000/property 401 (Unauthorized)
What is the mistake?
Cheers.
PS
this is
angular.module('MainApp')
.factory('s_auth', ['$http', '$window', function($http, $window){
var auth = {};
auth.saveToken = function (token) {
$window.localStorage['current-user-token'] = token;
};
auth.getToken = function() {
return $window.localStorage['current-user-token'];
};
}
service
Looks like you are not sending the JWT token to your backend.
TO be sending it try adding headers { authorization: "{TOKEN}"} in your post request

Increment the Mongoose query limit by button click/scroll in AngularJS

I want to increment the data via Button click or scroll.
I have a function which loads the data after button click loadDataQueryDB(param, param, param). With that, I am passing data to MongoDB query.
Well how can I increment my var limit = 50; + 5; after each button click?
Node.js
router.get('/load', function(req, res) {
var skip = 0;
var limit = 50;
var place_val = req.query.place;
var category_val = req.query.category;
var specCategory_val = req.query.specCategory;
if(category_val, specCategory_val, place_val){
Experiences
.find({category : category_val, city:place_val})
.lean()
.skip(skip)
.limit(limit)
.exec(function(err, docs_accommo) {
res.send(docs_accommo);
console.log("First");
});
}
});
Angular.js
app.controller('loadData', ['$scope', '$http', '$window', '$upload', '$rootScope',
function($scope, $http, $window, $upload, $rootScope) {
$scope.loadDataQueryDB = function(place_value, category_value, specCategory_value){
console.log(place_value);
console.log(category_value);
console.log(specCategory_value);
$scope.datafront = [];
var options = {
place : place_value,
category: category_value,
specCategory : specCategory_value
};
$http.get('/load',
{params: options})
.success(function(data) {
$scope.datafront = data;
});
};
});
HTML
<div ng-click="loadDataQueryDB(place, category, specCategory)">
<div ng-repeat="x in datafront | limitTo:? track by x._id" ng-cloak>
{{x}}
</div>
</div>
<button class="btn btn-default" style="float:right; margin-bottom:20px;"/>
Something like the code below, using services and http promises, the data returned form the server its on promise.data.
app.controller('loadData', ['$scope', '$http', '$window', '$upload', '$rootScope','dataService',
function($scope, $http, $window, $upload, $rootScope, dataService) {
$scope.loadDataQueryDB = function(place_value, category_value, specCategory_value){
console.log(place_value);
console.log(category_value);
console.log(specCategory_value);
$scope.datafront = [];
var params = {
place : place_value,
category: category_value,
specCategory : specCategory_value
skip : $scope.skip,
limit : $scope.limit
}
dataService.getData(params).then(function(promise){
$scope.dataFront = promise.data;
//Increment the limit by ten
$scope.limit =+ 10;
})
};
});
app.module('dataService').factory('dataService',['$http',function ($http) {
var service = {};
factory.getData= function (params) {
var promise = $http({
method: 'GET',
url: '/load',
params: params
});
return promise;
}
return service;
}]);
You should have only the gets that return views on the router and the rest of the get and post calls on a service, at least I develop like that and its more confortable.

$http.post from angular form not sending any data

I have a form that is posting /api/tradelink but it doesn't send any body or data with it.
HTML :
<form ng-submit="sendTradelink()">
<md-input-container class="md-accent">
<label>Enter your tradelink</label>
<input ng-model="tradelink">
</md-input-container>
<md-button type="submit" class="md-raised md-accent">Send</md-button>
</form>
Services :
.factory('Auth', ['$http', '$api', '$window', function ($http, $api, $window) {
var authFactory = {};
authFactory.authenticate = function(){
$http.post($api.url + 'auth')
.successs(function(url){
$window.location.href = url;
});
};
authFactory.send = function () {
return $http.post($api.url + 'tradelink');
};
return authFactory;
}]);
Controller ;
.controller('AppCtrl', ['$scope', 'Auth', '$location', '$cookies', function ($scope, Auth, $location, $cookies) {
var sidTemp = 'needtomakeitanewvalue';
$scope.checklogin = function () {
$scope.sid = $cookies.get('sid2');
console.log($scope.sid);
}
$scope.sendTradelink = function () {
Auth.send($scope.tradelink)
.success(function (res) {
$scope.sidTemp = 'needtomakeitanewvalue';
$cookies.put('sid2', sidTemp);
$location.path('/');
});
}
$scope.auth = function () {
Auth.authenticate();
}
}])
Server side holding api request, nothing inside req.body or req.params. Both show as empty objects.
api.post('/tradelink', function(req, res){
console.log(req.user.steamId);
console.log(req.params);
console.log(req.body);
res.json({
success: true,
message: 'tradelink received'
})
});
Check the Angular docs for $http.post
You are calling Auth.send($scope.tradelink), but your authFactory.send() function needs to accept this tradelink value and then be used as a data param to $http.post()
So:
authFactory.send = function (tradelink) {
return $http.post($api.url + 'tradelink', {tradelinkId: tradelink });
};

Expected response to contain an object but got an array

I get this error, I found many thread with the same message, but it never seems to match my case, and I didn't manager to solve it.
Basivally, everything was ok until I tried to make 1 form for create and update a 'Car' object.
Here is a presentation of my app (build from this template: https://github.com/linnovate/mean):
/public/js/config.js:
[...]
.state('edit car', {
url: '/cars/:carId/edit',
templateUrl: 'views/cars/edit.html'
})
.state('create car', {
url: '/cars/create',
templateUrl: 'views/cars/edit.html'
})
/public/js/services/mycars.js (don't really know what services are used for...):
//Cars service used for car REST endpoint
angular.module('mean.mycars').factory('Cars', ['$resource', function($resource) {
return $resource('cars/:carId', {
carId: '#_id'
}, {
update: {
method: 'PUT'
}
});
}]);
public/js/controllers/mycars.js:
angular.module('mean.mycars').controller('MyCarsController', ['$scope', '$http', '$stateParams', '$location', 'Global', 'Cars',
function ($scope, $http, $stateParams, $location, Global, Cars) {
$scope.findOneOrCreate = function () {
// create a new car
var car = new Cars({
id : null,
marque: this.marque,
modele: this.modele,
desc: this.desc
});
// put new car in scope
$scope.car = car;
// if there is a param, search for the car (mode update)
if ($stateParams.carId !== null){
Cars.get({
carId: $stateParams.carId
}, function(carTmp) {
// put the result in scope
$scope.car = carTmp;
});
}
};
$scope.createOrUpdate = function () {
var car = $scope.car;
if (car.id !== null) {
// update
if (!car.updated) {
car.updated = [];
}
car.updated.push(new Date().getTime());
car.$update(function () {
$location.path('cars/' + car._id);
});
}
else {
//Create
car.$save(function (response) {
$location.path('cars/' + response._id);
});
}
};
And finally my view: edit.html:
<section data-ng-controller="MyCarsController" data-ng-init="findOneOrCreate()">
<form class="form-horizontal col-md-6" role="form" data-ng-submit="createOrUpdate()">
<div class="form-group">
<label for="title" class="col-md-2 control-label">Title</label>
<div class="col-md-10">
<input type="text" class="form-control" data-ng-model="car.modele" id="title" placeholder="Title" required>
</div>
</div>
<div class="form-group">
<label for="content" class="col-md-2 control-label">Content</label>
<div class="col-md-10">
<textarea data-ng-model="car.marque" id="content" cols="30" rows="10" placeholder="Content" class="form-control" required></textarea>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-default">Submit</button>
</div>
</div>
</form>
</section>
Edit to add infos:
The web Services are supposed to return only one car (but not sure if they do), here they are:
exports.car = function(req, res, next, id) {
Car.load(id, function(err, car) {
if (err) return next(err);
if (!car) return next(new Error('Failed to load car ' + id));
req.car = car;
next();
});
};
exports.create = function(req, res) {
var car = new Car(req.body);
car.user = req.user;
car.save(function(err) {
if (err) {
return res.send('users/signup', {
errors: err.errors,
car: car
});
} else {
res.jsonp(car);
}
});
};
exports.update = function(req, res) {
var car = req.car;
car = _.extend(car, req.body);
car.save(function(err) {
if (err) {
return res.send('users/signup', {
errors: err.errors,
car: car
});
} else {
res.jsonp(car);
}
});
};
Error message appears when I go to /cars/create, not when I go to /cars/:carsId/edit:
Error: [$resource:badcfg] Error in resource configuration. Expected response to contain an object but got an array
http://errors.angularjs.org/1.2.15/$resource/badcfg?p0=object&p1=array
Is your web service returning an array? The get method expects only one object to be returned, and the same with your PUT request if you're returning something. If you're expecting multiple you will need to specify isArray: true in your service method in mycars.js. See example here: http://docs.angularjs.org/api/ngResource/service/$resource

How to change resource's headers in angularjs

I'm trying to set the headers of a resource (code bellow).
It happens that, when I instantiate my resource ($scope.user = new rsrUser;) angularjs fetches the cookies that aren't yet defined (an "undefined" error is fired from inside "getHMAC()"). The cookies will only be defined when "$scope.login()" is fired (it happens when the user clicks a button in the interface).
Is there a better way of doing this?
controllers.js
angularjsWebInterfaceControllers.controller('loginCtrl', ['$scope', 'rsrUser',
function($scope, rsrUser){
$cookieStore.put("username","therebedragons");
$cookieStore.put("password","therebedragons");
$scope.user = new rsrUser;
$scope.user.username = ""; //bound to input field in interface
$scope.user.password = ""; //bound to input field in interface
$scope.login = function() {
$cookieStore.put("username", $scope.user.username);
$cookieStore.put("password", $scope.user.password);
$cookieStore.put("state", "loggedOUT");
$scope.user.$logIn(
function(){
$cookieStore.put("state", "loggedIN");
}, function() {
$cookieStore.put("username","therebedragons");
$cookieStore.put("password","therebedragons");
$cookieStore.put("state", "loggedOUT");
}
)
};
}]);
services.js
angularjsWebInterfaceServices.service('rsrUser', [ '$resource', '$cookieStore',
function($resource, $cookieStore){
var req = "/login"
var timestamp = getMicrotime(true).toString();
var username = $cookieStore.get("username");
var key = $cookieStore.get("password");
return $resource(baseURL + req, {}, {
logIn: {method:'POST',
isArray:false,
headers:{
'X-MICROTIME': timestamp,
'X-USERNAME': username,
'X-HASH': getHMAC(username,timestamp,req,key)
}
}
});
}]);
EDIT: Actually, the cookies are defiend as soon as the controller is instantiated;
The value for a header can be a function that returns a string (see arguments here: http://docs.angularjs.org/api/ng/service/$http#usage). That way the cookie isn't accessed in your resource until the logIn method is called.
return $resource(baseURL + req, {}, {
logIn: {method:'POST',
isArray:false,
headers: {
'X-MICROTIME': timestamp,
'X-USERNAME': function() {
return $cookieStore.get("username");
},
'X-HASH': function() {
var username = $cookieStore.get("username");
return getHMAC(username,timestamp,req,key)
}
}
}
});

Categories

Resources