I am new to AngularJS and am trying out a few things with posting and deleting content using $resource. I've got the posting working fine, but when I try to delete something that I've posted I get a 404 error.
DELETE http://localhost:3000/tasks?__v=0&_id=53c5ddcf2978af0000ccdc50&beginningDat…vacy=true&title=This+is+a+complete+task&website=http:%2F%2Fwww.hotmail.com 404 (Not Found)
I've been working on this for a few days now and I'm just not seeing what i am missing. I am using a MEAN stack. I've got mongoose, express, bodyParser, and cors as dependencies in my app.js and created my endpoints:
app.get('/tasks', api.getTask);
app.post('/tasks', api.postTask);
app.delete('/tasks/:_id', api.deleteTask);
Here is the code from my api.js which
exports.deleteTask = function(req, res){
var _id = req.params._id;
Task.remove({_id:_id}, function(err, task){
res.send(task + ' removed task successfully');
if(err){
res.send('Hey guys...he is still here.');
}
});
};
Here is my factory/service:
'use strict';
angular.module('achievementApp').factory('tasks', function($resource){
return $resource('http://localhost:3000/tasks/',{_id: '#_id'},{
get: {method:'GET', isArray: true},
add: {method:'POST'},
delete: {method: 'DELETE'}
});
});
And here is the code from the Ctrl:
$scope.taskList = tasks.get({});
$scope.removeTask = function(obj){
tasks.delete(obj);
var index = $scope.taskList.indexOf(obj);
console.log(index);
$scope.taskList.splice(index,1);
console.log('removeTask was called');
};
Any guidance on this would be greatly appreciated. I've tried just about everything I can to get it to work and have had no luck so far.
It looks like you have a mismatch between the angular code which is putting the _id in the query string and the express code which is looking for it as a route param, which looks in the path part of the URL. req.params comes from the path part before the ?. req.query comes from the query string part after the ?. It would be more conventional to use the path in terms of REST, so I suggest changing your angularjs code to have /tasks/:_id as the resource route.
Aside: Best to use relative paths in your browser JS and omit the protocol, host, and port. Otherwise your app won't work when you deploy it on the real web.
Related
I'm creating a website using React and Express GraphQL, with a MariaDB database. I've come across a problem with making frequent requests/subscriptions to the GraphQL API, however.
After the page in question loads in React, I call this:
componentDidMount() {
this.setState({
waitingTimer: setInterval(this.queryWaiting.bind(this), 1000)
});
}
where queryWaiting is a function that carries out a fetch request to my GraphQL server at localhost:3000/graphql. That URL itself is a proxy defined in my setupProxy.js file which proxies the URL from localhost:4000/graphql, so that I don't need to use CORS.
It's worth noting that I also clearInterval this waitingTimer in componentWillUnmount.
In my GraphQL server file, which I'm simply running with node, I set up my server like this:
var app = express();
app.use("/graphql", graphqlHTTP({
schema: schema,
rootValue: root,
graphiql: true,
}));
app.listen(4000);
Where schema is a valid schema, and root is my root resolver.
The API query that I'm repeatably calling is called getWaitingCount, and it acts like this:
getWaitingCount: () => {
return new Promise((resolve, reject) => {
var currentTime = Date.now() / 1000;
if (cachedWaitingTime + cachedWaitingInterval > currentTime) {
return cachedWaiting;
}
connection.query("SELECT COUNT(*) FROM profiles WHERE isWaiting=1;", function (error, results, fields) {
if (error)
reject(error);
else {
// Update cache values
cachedWaiting = results[0]["COUNT(*)"];
cachedWaitingTime = Date.now() / 1000;
resolve(cachedWaiting);
}
});
});
}
I've implemented some caching to reduce server load. The caching variables are defined elsewhere.
The problem I experience is that, after between 2-10 seconds, the POST requests for this specific query from my React app stop getting resolved, and I have to reload the page for them to start getting accepted again. Weirdly, other requests go through fine.
I've tried various solutions, such as switching to using the proxy method I'm using currently, and I've also considered the possibility of a built-in anti-DDOS mechanism in the Express code, but I can't find any evidence for that.
Any help with this issue is very much appreciated.
Turns out the best solution is to type out and explain your code :)
This code:
if (cachedWaitingTime + cachedWaitingInterval > currentTime) {
return cachedWaiting;
}
is inside a promise, so really, it should do:
resolve(cachedWaiting);
instead of returning it.
That is all. I am currently kicking myself.
Hi everyone i am new to node.js and express. i am just experimenting with various node.js code from various tutorials.
As per the official npm website correct syntax to use methodOverride is
// Be sure to place after the body parser if you want to accept the method
// override using a post parameter
app.use(express.bodyParser());
// Accepts a single argument, the name of the method override parameter,
// defaults to "_method"
app.use(require('express-method-override')('method_override_param_name'));
But when i used this, i got the following error
Error: Most middleware (like bodyParser) is no longer bundled with Express and
ust be installed separately. Please see https://github.com/senchalabs/connect#m
ddleware.
at Function.Object.defineProperty.get (E:\node_modules\npm\node_modules\exp
ess\lib\express.js:89:13)
As far as i researched app.use(express.bodyParser()) is deprecated. Express no longer includes the bodyParser middleware. So to my guess app.use(bodyParser()) is right and i altered my code like this
app.use(bodyParser());
app.use(require('express-method-override')('method_override_param_name'));
Below is my put functionality code
app.put('/user/:id', function(req, res){
console.log('Sha Put testing');
console.log(req.body);
//user.findByIdAndUpdate({email: req.params.id},
user.update({email: req.params.id},
{
email: req.body.email,
name: req.body.name,
age : req.body.age
},
function(err, docs){
if(err) res.json('Error here paiyaa -->' + err);
else
{
console.log(docs);
res.redirect('/user/'+req.body.email);
}
});
});
When i replace app.put with app.post it works fine. But my task is to achieve PUT functionality.As mentioned in express-method-override source, I have used hidden field with the name _method, which helps to override POST method, and facilitates PUT method.
My Edit form code is
<h1>Editing #{user.name}'s profile!</h1>
form(method="POST", action="/user/#{user._id}")
input(type="hidden", name="_method", value="PUT")
p Name:
input(type="text", name="name", value="#{user.name}")
p Age:
input(type="number", name="age", value="#{user.age}")
p
input(type="submit")
When i run the above code it throws below error while submitting the form
Cannot POST /user/test#gmail.com
Can some expert help me to fix this and understand bit clear please
You have a PUT route defined with app.put, but are trying to POST to it. The verbs need to match up, so either your request should be a PUT (makes sense for your user.update method) or change the route to app.post.
EDIT:
Looking at the source for express-method-override, your request body needs to have a _method: 'PUT' (as a default -- currently you are passing 'method_override_param_name' property on it in order for the middleware to override the POST verb.
If you are not already, you should also be including the body-parser middleware. npm install body-parser on the commandline or add it to your package.json and run npm install. var bodyParser = require('body-parser'); will then give the rest of your code what it needs to include the middleware.
I have a url, i'm trying to get id but none of it is working req.params nor req.query
app.get('/test/:uid', function testfn(req, res, next) {
debug('uid', req.params.uid); // gives :uid
debug('uid', req.query.uid); // gives undefined
});
I'm doing an ajax call like this
$(document).on('click', 'a.testlink', function(e) {
$.ajax({
type: "GET",
url: '/test/:uid',
success: function(var) {
console.log('success');
},
error: function() {
alert('Error occured');
}
});
return false;
});
I'm using
app.use(express.json());
app.use(express.urlencoded());
instead of body parser
Your code is working as expected: The ajax call specifies url: '/test/:uid' which is what puts :uid in req.params.uid.
Try sending something else: url: '/test/123' and req.params.uid will contain 123
Here is an example that will work. I will give step by step instructions from the start:
express myproject
cd myproject
npm install
Open app.js and add in the following somewhere in the file - maybe right before the line app.get('/test/:uid',test);
var test = function(req,res,next) {
// do whatever logic is needed
res.end('Displaying information for uid ' + req.params.uid);
}
app.get('/test/:uid',test);
Now, open up a new terminal, make sure you are in the myproject directory and enter:
node app.js
Now you can visit http://localhost:3000/test/45 on the local machine and you should see:
Displaying information for uid 45
If you are not accessing from your local machine make sure to change the url above to match whatever server your node app is running on.
Also, this is just a simple example. You might be better off organizing everything by placing the routes in files similar to the routes directory example setup in a new install of an express app. You can find more detailed examples of this on the web like this one and this one. Also, one of the best explanations of organizing/reusing code in Node this I have seen is in the book NodeJS in Action.
I've managed to get my handlebars working in a node+express app and loading in data from tweets based on a hashtag which I'm retrieving no problems and rendering the tweets on the page the first time no problem.
The issue I have now is trying to update the template with new tweets that come in.
I have in my routes the following code:
new twitter.TwitterStream().getHashTagStream(tweetsRetrieved);
function tweetsRetrieved(tweets) {
twitterSearchResults = tweets;
}
module.exports = function(app) {
app.get('/', function (req, res){
res.render('index', twitterSearchResults);
});
};
I've tried setIntervals around the rendering and getTweets method and when console logging I do see my response from Twitter with the latest tweets but the template isn't updating.
Any help would be greatly appreciated.
Thanks
Tom
Here's the basic setup. I'm trying to create a simple middleware component that would allow me to easily pass data from my route directly to my javascript in the client side. (Very similiar to the Gon gem in ruby). The way I'm doing it is by having a module that looks like this:
module.exports = function(){
return function(req,res,next){
var app = req.app;
if(typeof(app) == 'undefined'){
var err = new Error("The JShare module requires express");
next(err);
return;
}
res.jshare = {};
app.dynamicHelpers({
includeJShare: function(req,res){
if(typeof(res.jshare) === 'undefined'){
return "";
}
return function(){
return '<script type="text/javascript">window.jshare=' + JSON.stringify(res.jshare) + '</script>';
}
}
});
next();
};
}
Then, in my route I can do this:
exports.index = function(req, res){
res.jshare.person = {firstName : "Alex"};
res.render('index', { title: 'Express' })
};
Finally in the layout.jade:
!{includeJShare()}
What that does is in outputs a line of javascript on the client that creates the exact JSON object that was created server side.
Here's the question; it all works as expected, but being new to Express and Node.js in general, I was just curious if attaching properties onto the response object is OK, or is there something wrong with doing it that I'm simply overlooking? For some reason it doesn't pass my "smell test" but I'm not sure why.....
I know this is an old thread, but there is something else to add to this topic.
Express has a response.locals object which is meant for this purpose - extending the response from middleware to make it available to views.
You could add a property directly to the response object, and as #hasanyasin indicated, is how JavaScript is designed. But Express, more specifically, has a particular way they prefer we do it.
This may be new in express 3.x, not sure. Perhaps it didn't exist when this question was asked.
For details, see
http://expressjs.com/en/api.html#res.locals
There is also an app.locals for objects which don't vary from request to request (or response to response I suppose).
http://expressjs.com/en/api.html#app.locals
See also: req.locals vs. res.locals vs. res.data vs. req.data vs. app.locals in Express middleware
It is perfectly OK. It is how JavaScript is designed. Only thing you should be careful is to not accidentally overriding already existing properties or being overridden by others. To be safer, instead of adding everything directly to req/res objects, you might consider going a level deeper:
res.mydata={}
res.mydata.person= ...
Like that.
Use res.locals for including custom variables in your response object.