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
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
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.
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 });
};
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
I'm building a simple Contact Management app with Crud using AngularJS 1.0.0rc8.
Getting a list of currently existing contacts is no problem, but while attempting to save a new Contact to the server, a new row is created - complete with the correct id, created_at, and updated_at values - but the rest of the models data is ignored.
Here is a screenshot to show what I mean:
As you can see, numbers 4 and 5 were given the Id's but first_name, last_name, and phone_num were not saved to the database.
I am using a $scope.addContact function within the Controller that deals with the object.
Here is the entire code for the Contact List Controller:
'use strict';
function ContactListCtrl($scope, $http) {
$http.get('/contacts').success(function(data) {
$scope.contacts = data;
});
$scope.addContact = function(data) {
$http.post('/contacts/', data).success(function(data) {
console.log(data);
data.first_name = $("#new_contact_first_name").val();
data.last_name = $("#new_contact_last_name").val();
});
this.newFirstName = '';
this.newLastName = '';
};
};
After clicking 'Save' on the new-contact.html partial, the Object is logged to the Console, if I inspect its contents, than sure enough the values are collected - notice Jimi Hendrix is there:
Here is the form as it appears in the new-contact.html template:
<form id="contact_form" ng-submit="addContact()">
<input type="text" id="new_contact_first_name" name="newContactFirstName" ng-model="newFirstName" placeholder="First Name"></br>
<input type="text" id="new_contact_last_name" name="newContactLastName" ng-model="newLastName" placeholder="Last Name"></br>
<input type="button" id="contact_submit_btn" value="Add Contact" class="btn btn-primary">
</form>
The addContact() function is fired after the form is submitted with JQuery:
$(document).ready(function(){
$("#contact_submit_btn").click(function(){
$("#contact_form").submit();
});
});
(Something tells me that I may not be using the ng-model attributes correctly.)
Any ideas on where I am going wrong with this? Or ideas on how I can better go about implementing this design?
Thanks.
UPDATE BELOW:
Here is my entire updated controller code - with help from Sathish:
// contacts controllers
'use strict';
function ContactListCtrl($scope, $http, Contacts) {
$scope.contacts = Contacts.index();
$scope.addContact = function() {
var newContact = {
first_name: $scope.newContactFirstName,
last_name: $scope.newContactLastName
};
var nc = new Contacts({ contact: newContact });
nc.$create(function() {
$scope.contacts.push(nc);
// now that the contact is saved, clear the form data
$scope.newContactFirstName = "";
$scope.newContactLastName = "";
})
}
};
ContactListCtrl.$inject = ['$scope', '$http', 'Contacts'];
function ContactDetailCtrl($scope, $routeParams, Contacts) {
$scope.contact = Contacts.get( {contact_id: $routeParams.contact_id} );
}
ContactDetailCtrl.$inject = ['$scope', '$routeParams', 'Contacts'];
I am now receiving the error: Unknown Provider for Contacts. Here is a screenshot of the error
Ok, I managed to fix that error by providing a ngResource to the main App file. Here's what it looks like:
// main app javascript file
'use strict';
angular.module('contactapp', ['ngResource']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/contacts', {template: 'assets/app/partials/contact-list.html', controller: ContactListCtrl}).
when('/contacts/new', {template: 'assets/app/partials/new-contact.html', controller: ContactListCtrl}).
when('/contacts/:contact_id', {template: 'assets/app/partials/contact-detail.html', controller: ContactDetailCtrl}).
otherwise({redirectTo: '/contacts'});
}]);
I am receiving a new error: WARNING: Can't verify CSRF token authenticity
Alright, managed to fix that problem too by adding a callback to the API controller:
Rails shows "WARNING: Can't verify CSRF token authenticity" from a RestKit POST
Now I am back to the original problem. When the create method is called, a new row is saved to the database, but the models data is not.
Awesome... finally got this thing working.
The problem was the $scope.addContact function. It was using the 'name' of the input instead of the ng-model binding called 'newFirstName' and 'newLastName' that resides in the template.
Here's what the updated function looks like:
$scope.addContact = function() {
var newContact = {
first_name: $scope.newFirstName,
last_name: $scope.newLastName
};
var nc = new Contacts({ contact: newContact });
nc.$create(function() {
$scope.contacts.push(nc);
// now that the contact is saved, clear the form data
$scope.newFirstName = "";
$scope.newLastName = "";
})
}
This can be better implemented using a Contacts service. Please define a Contacts service in app/assets/javascripts/services.js.erb as shown below:
var servicesModule = angular.module('<your app name>',
[<list of modules needed by this app>]);
servicesModule.factory('Contacts', function($resource) {
var ContactsService = $resource('/contacts/:contact_id', {}, {
'create': { method: 'POST' },
'index': { method: 'GET', isArray: true },
'update': { method: 'PUT' },
'destroy': { method: 'DELETE' }
});
return ContactsService;
});
Change the addContact method in the controller as shown below:
function ContactListCtrl($scope, $http, Contacts) {
...
...
...
$scope.addContact = function () {
var newContact = {
first_name: $scope.newContactFirstName,
last_name: $scope.newContactLastName
};
var nc = new Contacts({ contact: newContact });
nc.$create(function() {
$scope.contacts.push(nc);
// now that the contact is saved, clear the form data.
$scope.newContactFirstName = "";
$scope.newContactLastName = "";
});
};
...
...
...
}
ContactListCtrl.$inject = ['$scope', '$http', 'Contacts'];
In addition to this, you can simplify the $http.get(...) part also. You can use Contacts.index();
Note:
If you gave ng-app="MyAppName" then please replace <your app name> with MyAppName.
<list of modules needed by this app> needs to the replaced by a comma-separated list of strings representing any modules needed by your application.
Check the attr_accessible on your model. With new 3.2.3 rails all model attributes became protected from mass-assignment by default.