PUT Request with AngularJS and Express - angularjs

When I'm performing a put request and console.log(response) of the request I only get a JSON Object like {"res":1} instead of getting the whole json object with its changes in order to update him in a database.
Controller :
$scope.doneEdit = function (components) {
console.log(components);
components.editing = false;
if (components.editing === false) {
$http.put('/propt/' + components._id).then(function (response) {
console.log(response.data);
});
}
}
Express
app.put('/propt/:id', function(req,res) {
console.log(req.body);
testDb.update({_id:req.params.id}, req.body, {}, function(err, numReplaced){
res.statusCode = 200;
res.send(req.body);
})
})

You should pass the data you want to send as a second parameter to put method:
$http.put('/propt/' + components._id, {someValue:components.someValue})
You can find the documentation here: https://docs.angularjs.org/api/ng/service/$http#put

Related

Getting 401 from fetch in React - Passing sessionId

I'm building react app, first screen is a login form that is calling a GET rest api resource in other host (8080)(CORS extension on chrome was installed to overcome CORS issue).
After logging in successfully, trying to perform another GET fetch but this time am getting 401!
Tried setting the credentials: 'same-origin' or credentials: 'include' (in both calls, login and second one) but it didn't help!
fetch('http://<some host>:8080/WebServices/api/SessionManager/login?userName='
+ this.state.userName + '&password=' + this.state.password,
{
//credentials: "include",
//mode: "no-cors"
})
.then(
(response) => {
if (response.status < 200 || response.status > 300) {
console.log('Looks like there was a problem. Status Code: ' +
response.status);
this.state.showError = true;
this.state.errorMessage = 'Please enter a valid credentials.';
return;
} else {
localStorage.setItem('session', response);
console.log("Response ======>", response);
window.location.href = '/main';
}
}
)
.catch((error) => {
console.error(error);
});
second call:
function getSession(){
return localStorage.getItem('session').then(response => JSON.parse(response))
}
function getProjectDetails(){
let params = getSession();
let headers = new Headers();
fetch('http://<host>:8080/WebServices/api/ProjectManager/getProjectDetails?userSessionId=', params
// {
// //credentials: "include",
// //credentials: "same-origin",
// //crossdomain: true,
// //mode: 'no-cors',
// //headers: headers
// }
)
//.then(res => res.json())
.then((data) => {
this.setState({ projectsDetails: data })
console.log(data);
})
.catch(console.log);
}
class App extends Component {
Is there a way to get the session from browser cookies and set it into the header or parameters of fetch? how can I solve it?
If I understand it right you are asking how to store and retrieve stored values from the cookies.
First you need to store the data you get from the first fetch with, be aware that must convert he json response to string with JSON.stringify.
localStorage.setItem('session', JSON.stringify(response));
An then you can retrieve it with:
localStorage.getItem('session');
LocalStorage has to be stored as json, and decode it after getItem().
So in order to add the session params to the second fetch you can do as follows:
function getSession(){
return JSON.parse(localStorage.getItem('session'))
}
// second fetch,
function secondFetch(){
var params = getSession();
// in var params you have the data stored so now you can do the second fetch
}
I hope I've been of help to you, anything don't hesitate to ask.

node.js API call and churned nicely into a clean list

So im trying to get this API to print out into an array. It does.. but not all of the information. I've tried a few loops and I could not get it to behave the way I needed it to. Any help would be appreciated
const request = require("request");
const url = "https://api.nicehash.com/api?method=stats.provider.workers&addr=3Hwm6i8aefzHhJTbEGtSJeR6tZCJXqY7EN";
request.get(url, (error, response, body) => {
let json = JSON.parse(body);
});
Edit: This is another attempt I've tried. However it returns a lot cleaner but still has all of the brackets, commas etc garbage. is there a way to clean that?
'use strict';
var request = require('request');
var url = 'https://api.nicehash.com/api?method=stats.provider.workers&addr=3Hwm6i8aefzHhJTbEGtSJeR6tZCJXqY7EN';
request.get({
url: url,
json: true,
headers: {'User-Agent': 'request'}
}, (err, res, data) => {
if (err) {
console.log('Error:', err);
}
else if (res.statusCode !== 200)
{
console.log('Status:', res.statusCode);
}
else {(!err && data && data.result && data.result.workers)
console.log(data.result.workers);
}
});

AngularJS $http.delete not working in Azure App Service

A follow-up on a similar question I posted yesterday. I am trying to delete data from a table in Azure App service. This is my function in my Angular file.
function delName(user) {
//$scope.categories.push(user);
alert("about to delete. Action cannot be undone. Continue?")
$http.delete('https://test-evangelists-1.azurewebsites.net/tables/people', user, config)
.then(function (res) {
$scope.getNames();
});
}
Then I added an HTML button:
<button id="btn-del-evangelist" class="btn btn-default btn" ng-click="delName(user);">Delete User</button>
This is the value of my headers variable:
var config = {
headers: {
'Access-Control-Allow-Origin':'*',
'ZUMO-API-VERSION': '2.0.0'
}
};
But when I tried to run it, the console returns the following error:
which states that the header for ZUMO-API-VERSION must be specified.
Below is my code for GET and POST
GET:
function getNames() {
$http.get('https://test-evangelists-1.azurewebsites.net/tables/people', config)
.then(function (res) {
console.log(res);
$scope.people = res.data;
});
}
POST
function addName(user){
//$scope.categories.push(user);
alert("about to post!")
$http.post('https://test-evangelists-1.azurewebsites.net/tables/people', user, config)
.then(function (res) {
$scope.getNames();
});
}
Since I have already specified the header in my variable, I wonder what can be wrong here. Any help will be appreciated.
UPDATE:
I figured out that the Id must be appended to the URL before I can perform delete. However, I need to run a GET to retrieve the ID given the parameters but I am still encountering errors when getting the ID.
This is now my Delete function
function delName(user) {
alert("About to delete. Action cannot be undone. Continue?")
var retrievedId = "";
$http.get('https://test-evangelists-1.azurewebsites.net/tables/people', {
params: { name: user.name, location: user.location },
headers: { 'Access-Control-Allow-Origin': '*', 'ZUMO-API-VERSION': '2.0.0' }
})
.then(function (res) {
retrievedId = res.id;
alert(retrievedId);
});
$http.delete('https://test-evangelists-1.azurewebsites.net/tables/people/' + retrievedId, config)
.then(function (res) {
$scope.getNames();
});
}
Does anyone know what is wrong in the GET command when getting the ID?
UPDATE 2: I have written instead an Web Method (asmx) that will connect to SQL server to retrieve the ID passing the needed parameters. The ID will be returned as a string literal but in JSON format. Then I called JSON.parse to parse the string into JSON object then assigned the ID to a variable to which I appended in the URL. –
This is now my Delete function after I have written the Web Method.
function delName(user) {
var confirmres = confirm("You are about to delete this record. Action cannot be undone. Continue?");
var retrievedId = "";
if (confirmres == true) {
//get the ID via web service
$http.get('\\angular\\EvangelistsWebService.asmx/GetId', {
params: { name: user.name, location: user.location },
headers: { 'Access-Control-Allow-Origin': '*', 'ZUMO-API-VERSION': '2.0.0' },
dataType: "json",
contentType: "application/json; charset=utf-8"
})
.then(function (res) {
$scope.retData = res.data;
var obj = JSON.parse($scope.retData);
angular.forEach(obj, function (item) {
if (item.length == 0)
alert('No data found');
else {
//perform delete after getting the ID and append it to url
$http.delete('https://test-evangelists-1.azurewebsites.net/tables/people/' + item.id, config)
.then(function (res) {
$scope.getNames();
});
alert(item.id + ' deleted');
}
});
});
}
}
That is one way that I have learned on how to call HTTP DELETE on AngularJS. But I don't know if that is the optimal one. In any case, that works for me, unless there will be other suggestions.
$http.delete only has one parameter (config), not two (data, config).
Delete API
delete(url, [config]);
vs.
Post API
post(url, data, [config]);
To your updated problem:
To delete an item from your table, it appears the correct url is:
/tables/tablename/:id
Note the : before id.

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

AngularJS reload data after PUT request

Should be a fairly easy one here for anyone who knows Angular. I am trying to update the data that is displayed after I make a PUT request to update the object. Here is some code:
Post service (services/post.js)
'use strict';
angular.module('hackaboxApp')
.factory('Post', function($resource) {
return $resource('/api/posts/:id', {id : '#id'}, {
'update': { method: 'PUT' }
})
});
Server side controller function that gets executed when trying to update data (lib/controllers/api.js)
exports.editsave = function(req, res, next) {
var posty = req.body;
console.log(posty._id.toString() + " this is posty");
function callback (err, numAffected) {
console.log(err + " " + numAffected);
if(!err) {
res.send(200);
//res.redirect('/forum');
}
}
Post.update(posty, { id: posty._id.toString() }, callback);
};
This is the console output for the above code:
53c54a0d4960ddc11495d7d7 this is posty
null 0
So as you can see, it isn't affecting any of the MongoDB documents, but it also isn't producing errors.
This is what happens on the client (Angular) side when a post is updated:
$scope.saveedit = function() {
console.log($scope.post._id + " post id");
// Now call update passing in the ID first then the object you are updating
Post.update({ id:$scope.post._id }, $scope.post, function() {$location.path('/forum')});
};
After the redirect, $location.path('/forum'), none of the data is displayed as being updated...when I look in the database...nothing has changed either...it is like I am missing the step to save the changes...but I thought that update (a PUT request) would do that for me.
I use ng-init="loadposts()" when the /forum route is loaded:
$scope.loadposts = function() {
$http.get('/api/posts').success(function (data) {$scope.posts = data});
};
Shouldn't all the new data be loaded after this? Any help would be appreciated. Thanks!
Your server side output indicate that the update query doesn't match any document in the database.
I'm guessing that you are using Mongoose in NodeJS server side code to connect to mongodb.
If that the case, your update statement seems incorrect.
Instead of { id: .. } it should be { _id: .. }
Also the conditions object and updated object are swapped.
The statement should be like this:
Post.update({ _id: posty._id.toString() }, posty, callback);
If you are not using Mongoose, please eloborate more on which library you are using or better than that, show the code where the Post variable is defined in your server side code.
Ok I got it.
the problem is that you are not using the Angular resource api correct.
This code need to be changed:
$scope.saveedit = function() {
console.log($scope.post._id + " post id");
Post.update({ id:$scope.post._id }, $scope.post, function() {$location.path('/forum')});
};
Into:
// Update existing Post
$scope.saveedit = function() {
var editedpost = new Post($scope.post); //New post object
editedpost.$update(function() {
$location.path('/forum');
}, function(errorResponse) {
$scope.error = errorResponse.data.message;
});
};
And as for the server code (taken from my own working module):
exports.update = function (req, res) {
var post == req.post;
post = _.extend(post, req.body);
post.save(function (err) {
if (err) {
return res.send(400, {
message: getErrorMessage(err)
});
} else {
res.jsonp(post);
}
});
};

Resources