Error In $http PUT - angularjs

I'm building a simple auction site. I showed my products in the page. Now i wanna make a new offer. in my controller i use ng-dialog to open a pop-up form and i pass inside the auction that i need. like this:
$scope.clickToOpen4 = function (followingauction) {
console.log(followingauction.allbids[followingauction.allbids.length -1].bid);
var newScope = $scope.$new();
newScope.auction = followingauction;
ngDialog.open({template: '../views/partials/offer.html',
className: 'ngdialog-theme-default',
scope: newScope
});
};
In my template offer.html i have a simple form:
<form name="Offer" ng-controller="FollowingAuctionsController">
Your Offer:<br>
<input type="number" placeholder="Your Offer" ng-model="newOffer" name="new offer" required> €<br>
<input class="btn" type="submit" ng-click="submitNewOffer(auction._id, auction.allbids[auction.allbids.length -1].bid)" value="OK"><br>
And in the submitNewOffer i pass, the id of the auction and the highest offer.
And this is the submitnewOffer():
$scope.submitNewOffer = function (id, bid) {
console.log(id);
console.log(bid);
var newBid = $scope.newOffer;
if (newBid>bid) {
console.log(newBid);
console.log('/api/followingauctions/newoffer/' + id);
$http.put('/api/followingauctions/newoffer/' + id, newBid)
.then(function () {
alert('Offert Done!');
getFollowingAuctions();
});
}
else {
alert('The offer must be higher!');
$scope.newOffer = '';
}
};
Like you see i do the console.log to see if the data that i passed into the template are ok. They are!
Than if the new bid is less than the highest bid that i passed, i send that alert, else i put the new offer.
All works fine and all the console.log are fine. But when i submit the newBid (that is higher than the old bid) it send me this error:
angular.js:12578 PUT http://localhost:3001/api/followingauctions/newoffer/58dbd190b8042b080d1418bf 400 (Bad Request)
angular.js:14516 Possibly unhandled rejection: {"data":"Unexpected token 8400SyntaxError: Unexpected token 8\n at parse (/Users/m.pagano/WebstormProjects/Challenge_2/Project2/sampsite/node_modules/body-parser/lib/types/json.js:83:15)\n at /Users/m.pagano/WebstormProjects/Challenge_2/Project2/sampsite/node_modules/body-parser/lib/read.js:116:18\n at invokeCallback (/Users/m.pagano/WebstormProjects/Challenge_2/Project2/sampsite/node_modules/raw-body/index.js:262:16)\n at done (/Users/m.pagano/WebstormProjects/Challenge_2/Project2/sampsite/node_modules/raw-body/index.js:251:7)\n at IncomingMessage.onEnd (/Users/m.pagano/WebstormProjects/Challenge_2/Project2/sampsite/node_modules/raw-body/index.js:307:7)\n at emitNone (events.js:86:13)\n at IncomingMessage.emit (events.js:185:7)\n at endReadableNT (_stream_readable.js:974:12)\n at _combinedTickCallback (internal/process/next_tick.js:74:11)\n at process._tickCallback (internal/process/next_tick.js:98:9)","status":400,"config":{"method":"PUT","transformRequest":[null],"transformResponse":[null],"jsonpCallbackParam":"callback","url":"/api/followingauctions/newoffer/58dbd190b8042b080d1418bf","data":800,"headers":{"Accept":"application/json, text/plain, /","Content-Type":"application/json;charset=utf-8"}},"statusText":"Bad Request"}

You are using the method incorrectly.
The right signature of $http.put method is put(url, data, [config]);
So, your code could look like this:
$http.put('/api/followingauctions/newoffer/' + id, {newBid: newBid})
.then(function () {
// success
});
and you can access newBid from POST at the backend
OR
$http.put('/api/followingauctions/newoffer/' + id, {}, {params: {newBid: newBid}})
.then(function () {
// success
});
in which case, newBid can be obtained from GET at the backend

When doing a PUT request with $http, you have to specify the params:
$http.put('/api/followingauctions/newoffer/' + id, {}, params: {'newBid': newBid})
.then(function () {
alert('Offert Done!');
getFollowingAuctions();
});

Related

AngularJS $http PUT request

I am buiding a CRUD apps with AngularJS and Django REST API.
I have created get and post method successfully but not getting how to put request. i tried stackoverflow lots of problem and youtube but i couldnt sort it out.
my current controller is:
app.controller('crudCtrl', function($scope, $http) {
$http.get("http://127.0.0.1:8000/api/v1/contact/?format=json")
.then(function(response) {
$scope.contacts = response.data; //this is get method that displayed all the list of contact
});
$scope.formModel = {}; // this is same input.js, it is POST method to to send data to database
$scope.onSubmit = function () {
console.log("hey, i am submitting");
console.log($scope.formModel);
$http.post('http://127.0.0.1:8000/api/v1/contact/', $scope.formModel).
success(function (data) {
console.log(":)");
}).error(function (data) {
console.log(":(");
});
};
$scope.selectUser = function (contact) {
console.log(contact); // it will select the data exactly where you click
$scope.clickedUser = contact;
};
$scope.updateUser = function (argument) { // it will get the form editable exactly which contact you clicked
};
});
and my edit view is, when i click on edit buttion, the form will be appear:
<form>
<input type="text" ng-model="clickedUser.userid">
<input type="text" ng-model="clickedUser.name">
<input type="text" ng-model="clickedUser.email">
<input type="text" ng-model="clickedUser.phone">
<button type="submit" ng-click="updateUser()" data-dismiss="modal">Submit</button>
</form>
Point to be noted, the edit form working nice on client side but it doesnt send the data to backend/API/Database.
can anyone tell me how can i do $http.put request? i tried w3school, youtube, and stackoverflow problem.
i got huge solution but i couldnt solve it.
this is my api endpoint for anything: http://127.0.0.1:8000/api/v1/contact/ so if i want to update particular field, i have to go through this url: http://127.0.0.1:8000/api/v1/contact/1 in the end of the url is id
I hope it is clear to you
You can try this as well
$http({method: "PUT", url: URL}).
then(
function(response) {
}, function(response) {
});
Can you just use angular put?
See: https://docs.angularjs.org/api/ng/service/$http#put
var clientData = {
text: "Put this somewhere"
};
$http.put( url, clientData ).then( function( serverResponse ) {
console.log(serverResponse);
},( error )=>{
console.log(serverError);
});

Not able to update data in mongoDB using AngularJs

When I try to change the status of a blog , the status is not updating in database. Status is string field and is initially stored as 0 in database
api.post('/statuschange', function(req, res){
Blog.find({_id: req.query.blog_id}).update({$set:{'status': req.body.status}}, function (err, status) {
if(err){
res.send(err);
return;
}
if(req.body.status == '1') {
res.json('Blog added')
return;
}
if(req.body.status == '-1'){
res.json('Blog not added');
return;
}
});
})
api is working successfully on postman
factory file
angular.module('blogfact', ['authService'])
.factory('blogFactory', function($http, AuthToken){
var factory = {};
var token = AuthToken.getToken();
factory.changestatus = function(info, callback){
$http({
url: 'api/statuschange',
method:'POST',
headers:{'x-access-token':token},
params:{'blog_id': info},
})
.success(function(response){
callback(response)
})
}
return factory
})
the controller file
angular.module('blogCtrl', ['blogfact']);
.controller('BlogController', function(blogFactory, $routeParams){
var that=this;
blogid = $routeParams.id;
var getthatBlog = function(){
blogFactory.getthatBlog(blogid, function(data){
//console.log('[CONTROLLER] That Blog:',data);
that.blog = data;
})
}
this.changestatus = function(info){
blogFactory.changestatus(info, function(data){
getthatBlog();
})
}
})
html file
<div ng-controller="BlogController as blog">
<textarea ng-model="blog.status"></textarea>
<button class="btn btn-success" ng-click="blog.changestatus(blog._id)">Submit</button>
</div>
If your question is regarding the value in MongoDB not being updated, well it seams it is due to the status data missing in your POST request.
I recommend that in your HTML, send the whole blog object so that you have the blog's status as well:
<button class="btn btn-success" ng-click="blog.changestatus(blog)">Submit</button>
Then in your blogFactory add the data as such:
$http({
url: 'api/statuschange',
method:'POST',
headers:{'x-access-token':token},
params:{'blog_id': info._id},
data: {status: info.status} // <==
})
Now, you should be able get the blog status data in NodeJS server back-end via req.body.status.
Update
Try the following with mongoose's update method:
Blog.update({_id: req.query.blog_id}, {status: req.body.status}, function(err, numAffected){
...
});
Or, alternatively:
Blog.findOne({_id: req.query.blog_id}, function(err, blog){
blog.status = req.body.status;
blog.save();
});
Angular let's you modify collection data on the client-side, but to actually update it on your server you need to notify the server of your changes (via API).
There are a few ways to do this, but if you want seamless updating from client-side to server maybe give meteor a try.
http://www.angular-meteor.com/
https://www.meteor.com/
Your are sending the data in params and getting the data from req.body.
You should use req.query or req.param. Else, Send the data on body like below,
$http({
url: 'api/statuschange',
method: 'POST',
params: { 'blog_id': info },
data: { 'status': 1 }
})
Your are passing 1 parameter in client side and getting two parameters on server side(req.body.status, req.query.blog_id)
Where is the token value from ?
Check the simplified way to test your code
http://plnkr.co/edit/tyFDpXw2i0poICwt0ce0

MEAN.JS Contact Form

Trying to create a contact form and feedback form for my website. Here is my route and controller I'm using however I need to understand what's going on with my routes and how to capture the input fields from the form implement this inside MEAN.JS:
route.js:
app.route('/mail').get(mail.createmail);
app/controller.js:
exports.createmail = function(req, res) {
var mailOpts, smtpTrans;
// create reusable transporter object using SMTP transport
var transporter = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: 'administrator#radleaf.com',
pass: '34Girls34*goo'
}
});
// NB! No need to recreate the transporter object. You can use
// the same transporter object for all e-mails
// setup e-mail data with unicode symbols
var mailOptions = {
from: 'Fred Foo ✔ <foo#blurdybloop.com>', // sender address
to: 'ty#radleaf.com', // list of receivers
subject: 'Hello ✔', // Subject line
text: 'Hello world ✔', // plaintext body
html: '<b>Hello world ✔</b>' // html body
};
// send mail with defined transport object
transporter.sendMail(mailOptions, function (error, info) {
if (error) {
console.log(error);
} else {
console.log('Message sent: ' + info.response);
}
});
};
Not sure how this work with the HTML with the view:
<form action="mail">...</form>
If I understand the question correctly, you're asking how you can gather data which is input into a form, send that data to expressJS, and then use that data to send an outbound email.
If so, then here is your flow:
Step 1: Create a form in a view and map it to an AngularJS controller
<form name="contactForm" data-ng-submit="sendMail()">
Name: <input type="text" data-ng-model="contact_name">
Message: <input type="text" data-ng-model="contact_msg">
<button type="submit">
</form>
Step 2: In your AngularJS controller, use a $http request to send your data to your Express Route
$scope.sendMail = function() {
// Simple POST request example (passing data) :
$http.post('/mail', {name: contact_name, msg: contact_msg}).
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
}
Step 3: Use your ExpressJS Route as an API to call your ExpressJS Controller.
(It looks like you've got this bit covered)
app.route('/mail').get(mail.createmail);
Step 4: Receive and do something with the data passed through the $http POST
exports.createmail = function(req, res) {
var data = req.body;
Now you can use the data, like this
var mailOptions = {
from: data.name, // sender name
text: data.msg, // plaintext body
};
MeanJS 0.4.0 also has a working example of NodeMailer which might help: https://github.com/meanjs/mean/tree/0.4.0
With angularJS, you can remove the action attribute, and just use angularJS ngSubmit directive, and call a function in your controller which would now visit the endpoint with $http.get.

Express + Angular update route: Error: Cannot PUT

I'm trying to update a schema using form, however, both on app.put and app.post (which I've seen as a possible solution) i get
PUT https://myapp-demo.herokuapp.com/api/events/5523da4d97c5000300f6e713 404 (Not Found)
and error from ajax callback
Error: Cannot PUT /api/events/5523da4d97c5000300f6e713
on clientside, I make this request:
$scope.saveEvent = function(id) {
$http.put('../api/events/' + id, $scope.formData)
.success(function (data) {
$scope.events = data;
})
.error(function(data) {
console.log('Error: ' + data);
})
};
In express routes, I do this:
app.put('../api/events/:id', function (req, res){
var user = req.user;
var id = req.params.id;
var update = {
$set: {
title: req.body.title,
description: req.body.description,
}
};
Event.findByIdAndUpdate(id, update, function (err, event) {
if(!event) {
res.statusCode = 404;
return res.send({ error: 'Not found' });
}
console.log("event updated");
Event.find(function(err, events) {
if (err){
res.send(err)
};
res.json(events);
});
});
});
I tried to pass event._id differently, by using req.params.id and passing id with form like req.body.id, it all leads to the same result. I've also read about creating hidden input for helping method-override to override form methods. However, having this didn't help.
<input type="hidden" name="_method" value="put">
<md-button class="md-raised md-primary" ng-click="saveEvent(eventId)">Save</md-button>
UPDATE
Indeed, the initial proble was in my put route. I've found a new problem now. When I try to update it again, I get
Error: Object {error: "Not found"}
It happens even after I refresh page or restart server.
The following is invalid:
app.put('../api/events/:id'...
It needs to be in reference to the namespace, or in your case the root:
app.put('/api/events/:id'...

Ui.Bootstrap Typeahead not working with Async call

I am using ui.bootstrap typeahead with an async call. However the resulting data does not seem to be finding it ways back to the typeahead directive and subsequently no dropdown appears with data.
The html is
<input type="text" ng-model="asyncSelected" placeholder="Search Profile" typeahead="username.username for username in getSearch($viewValue)" typeahead-wait-ms="400" class="form-control">
And the JS function is here
$scope.getSearch = function (val) {
return $sails.get("/search/" + val).success(function (response) {
console.log(response);
return response.map(function (item) {
console.log(item.username);
return item.username;
});
}).error(function (response) {
console.log('The sails profile search has failed');
});
}
The response JSON object is
Object
#type: "d"
id: "#17:3"
username: "Burt"
__proto__: Object
I am using angular-sails on the client to query the backend. I have tested the code with the sample given on the ui.bootstrap documentation and everything works ok.
The $sails.get also works as the console.log(item.username) prints out the values.
I have a feeling its got to do with the promise in the getSearch function.
Any ideas why the dropdown is not appearing?
I updated the sails from 10.5 to 11. Subsequently the client SDK changed (Sails.io) and the angular libraries I was using Angular-Sails also needed to be updated.
The promise functions changed and i needed to update it. Changing the promise function to the one below fixed the problem. Now the typeahead function gets a response and the dropdown appears.
return $sails.get("/search/" + val)
.then(function (response) {
console.log(response);
return response.data.map(function (item) {
return item.username;
});
}, function (response) {
alert('Houston, we got a problem!');
});

Resources