trouble building react component that has ajax calls - javascript

I am trying to build a simple node.js app using reactjs tutorial on comment box example.
I am having trouble saving comments to database, which is mongodb.
Here's the code,
comment_box.jsx
var CommentBox = React.createClass({
loadCommentsFromServer: function() {
var commBox = this;
$.ajax({
url: commBox.props.url,
dataType: 'json',
cache: false
}).done(function(data) {
commBox.setState({data: data});
});
},
handleCommentSubmit: function(comment) {
var commBox = this;
var comments = this.state.data;
// Optimistically set an id on the new comment. It will be replaced by an
// id generated by the server. In a production application you would likely
// not use Date.now() for this and would have a more robust system in place.
comment.id = Date.now();
var newComments = comments.concat([comment]);
this.setState({data: newComments});
$.ajax({
url: commBox.props.url,
dataType: 'json',
type: 'POST',
data: comment
}).done(function(data) {
commBox.setState({data: data});
});
},
api.js
//api for listing and posting comments
//bring comments model
var Comment = require('../models/comment.js');
exports.post = function(req, res, err) {
new Comment({comment: req.comment, author: req.author}).save(function() {
if(!err) {
console.log('saved');
}
else {
console.log('save failed');
}
});
}
exports.list = function(req, res) {
Comment.find(function(err, comments) {
res.send(comments);
});
}
router.js
var express = require('express');
var Router = express.Router();
var path = require('path');
var api = require('../controllers/api.js');
Router.get('/', api.list);
Router.post('/', api.post);
module.exports = Router;
server.js
// set up the RESTful API, handler methods are defined in api.js
app.use('/api/v1/*', require('./server/routes/router.js'));
The error is in exports.post in api.js the req doesn't come with body for some reason, I tried debugging with node inspector but couldn't see what the problem. Any help would be much appreciated. Please let me know if you need me post any further details to understand the question. Basically, in console I get error ERR_RESPONSE_EMPTY.
more details on the error,
I am running node server on my apple machine os x el capitan, routing is done by using expressjs, after I load the page react mounts the components which contains a comment form where you can get to add comments and post them. So ,here when I hit post button the ajax call should post the comment to the database and react component will get updated. But , the post call is not happening. In my comment_box.jsx code you can see the post call. the bit I posted here in server.js will handle the routes. and I have a router.js file and api.js that contains methods for posting and listing comments.
I was expecting when a comment is submitted, the form submit will trigger the react function to do the ajax call and update the database. But, it's not happening I get ERR_RESPONSE_EMPTY.

Related

Using AJAX to call Node.js file to send SMS message

I'm new to Node.js but I understand that it's on the server-side. When I run my app.js file in Terminal, it sends the text message, but what I'm ultimately trying to do is have the user finish the form, and upon button press, send them a text message to verify their submission. I'm using the Twilio service to help accomplish this. It's currently not sending a message on button press.
Here's my app.js file:
var accountSid = process.env.TWILIO_ACCOUNT_SID;
var authToken = process.env.TWILIO_AUTH_TOKEN;
var client = require('twilio')(accountSid, authToken);
app.get('/testtwilio', function(req, res) {
client.messages.create({
to: "+1receivingNumber",
from: "+myTwilioNumber",
body: "Testing, testing, testing"
}, function(err, message) {
if (err) {
console.log(err);
} else {
console.log(message.sid);
}
});
})
And my Javascript file:
$('#buttons').on('click', function(e) {
$.ajax({
type: 'POST',
url: '/testtwilio',
data: {
"To": userCellPhone,
"From": "+1myTwilioNumber",
"Body": "Ahoy! Testing"
},
beforeSend: function(xhr) {
...
},
success: function(data) {
console.log(data);
},
error: function(data) {
console.log(data);
}
});
});
And lastly, my html button:
<button type="submit" id="buttons" class="buttons">SUBMIT</button>
Honestly, I'm not even sure this is possible, but I've been searching forever and can't really find any direct solution. Any help is appreciated!
Your app variable is undefined. If you want to use the express framework like in the tutorials you've followed, you need to register it in your app.js like follows:
var express = require('express');
var app = express();
Combined with the answers/comments about POST, that should see you on your way.
Nb. you'll need to install express in your node modules. From the command line in your root directory:
npm install --save express
nodeJs route expects GET. But your ajax makes POST request. Try:
app.post('/testtwilio', ...

Cannot GET on POST request

I have an API that takes in 3 url parameters and writes into a mongodb collection. My understanding is that it should be post request since it's sending data to my back end, but when sending the data in, I get a Cannot Get... error.
routes.js
// JavaScript source code
var friends = require('./../controllers/friends.js');
module.exports = function(app)
{
app.post('/friends/new/:fname/:lname/:bday', function (request, response)
{
friends.create(request, response);
})
}
Controller:
// JavaScript source code
var mongoose = require('mongoose');
var Friend = mongoose.model('Friend');
module.exports =
{
create: function(request, response)
{
var friendInstance = new Friend();
friendInstance.first_name = request.params.fname;
friendInstance.last_name = request.params.lname;
friendInstance.b_day = request.params.bday;
friendInstance.save(function(err)
{
if (err)
{
response.josn(err);
}
}
URL:
http://localhost:8000/friends/new/Gelo/Maverick/9999-9-99
Error:
Cannot GET /friends/new/Gelo/Maverick/9999-9-99
You're seeing that error because you must be trying to access the url via the web browser, which sends the GET request. You should use an app like Postman to make POST requests instead.

Update content of page from a POST request in Express

I had a problem where I tried to update the contents of the web page through a POST request that was done through a form but the problem is that the variables were set to the global scope and every time that I refreshed the page the content was still there. Somebody explained what was the issue and told me that I could "...make the post return a JSON object with the data instead of doing a redirect. Then do the POST async from the client and display the data." Here is the code that I'm using on:
Express:
var data;
var url;
/* GET home page. */
router.get('/', (req, res, next) => {
res.render('index', { 'data': data});
});
/* POST HANDLER */
router.post('/link', function(req, res, next) {
var pattern = /^((http|https|):\/\/)/;
url = req.body.link;
if (!pattern.test(url))
{
url = "http://" + url;
bitly.shorten(url)
.then(response => {
data = response.data.url;
res.redirect("/");
});
}
});
And I'm using jQuery for the POST request:
$('#shortLink').on('click', () => {
$.ajax({
type: 'POST',
url: '/link',
data: {link: $('#linkInput').val()},
success: data => {
console.log(data);
}
});
});
What I want to do is get the value of an input, send it to the POST handler on Express and then pass that information back to the home page without having to get out of the page; like a common Ajax request. Can somebody elaborate on what I was suggested to do, above? Or give me another solution.
There's no rule that says you have to redirect after handling a post request. Just send the data back via res.json({'url': response.data.url}), and then in your $.ajax success handler it will be available via data.url.

How do I set a global variable accessible throughout all routes express/node.js

I am getting my feet wet with nodejs and express and I am using Parse API for my backend database.
currently I have an ajax post on page load to one of my routers /getuser, which gets the current user if they are logged in.
I want to know what is the best way to implement this so that the user variable will be accessible across all routes, should I even be doing it this way ?
I basically want to be able to have access to the user throughout the app.
index.js routes
var express = require('express');
var router = express.Router();
Parse = require('parse').Parse;
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'hello'});
});
//GET USER
router.post('/getuser',function(req,res){
if(req.body.name != null){
username = req.body.name;
loggedIn = true;
res.send(JSON.stringify(username));
}
else{
loggedIn = false;
}
});
module.exports = router;
scripts.js client side ajax post on page load
Parse.initialize("xxxxx","xxxxxx");
var data = {};
data.name = Parse.User.current().get("username");
$.ajax({
url: "/getuser",
type: "post",
dataType: "json",
data: JSON.stringify(data),
contentType: "application/json",
cache: false,
timeout: 5000,
complete: function() {
},
success: function(data) {
console.log("success" + JSON.stringify(data))
},
error: function(data) {
console.log("error" + JSON.stringify(data))
},
});
Should I be posting this to my app.js and setting a global variable there ? How would I access that variable across all routes? How would I even post to app.js.
There are multiple pattern to share information accross all the routes. In your case it appear you want to share logged in user details with all the routes. For that I would do something like that.
Save logged in user in to session
There is req.session available if you are using express-session. Once your login is done you can save the logged in uid into req.session
Inject logged in user to routes
In your top level routes you can do something like this -
app.use(function(req,res,next){
if(req.session.uid){
//find the user via models , just an example, it should be async
var user = require('models').findUser(req.session.uid);
//inject to req object
req.currentUser = user;
//all the routes after this will have currentUser in the req
next();
} else {
//no user is logged in
console.log("Using empty user");
req.currentUser = null;
next();
}
});
Thus all the route after this will have currentUser depending upon logged in status.

Problems using Parse.Cloud.httpRequest with Express, says no such method for success:

I'm hitting a facebook graph search URL, in Parse Express. The call is made with a Parse.Cloud.httpRequest.
I get a 500 Internal Server Error response, and when I look in the logs I see:
an error saying that the httpRequest has no method named success: (even though the code i'm using is based right off examples on Parse.com).
The basic JSON data is there successfully retrieved but the error has prevented the function completing.
Here's the code, all tips appreciated:
// These two lines are required to initialize Express in Cloud Code.
var module = require('cloud/jsonml.js');
var Buffer = require('buffer').Buffer;
var express = require('express');
var app = express();
// Global app configuration section
app.set('views', 'cloud/views'); // Specify the folder to find templates
app.set('view engine', 'ejs'); // Set the template engine
app.use(express.bodyParser()); // Middleware for reading request body
app.get('/hello', function(request, response) {
Parse.Cloud.httpRequest({
url: 'a-facebook-graph-url',
success: function(httpResponse) {
console.log(httpResponse.data);
response.success(httpResponse.data);
var xml = module.stringify(httpResponse.data);
var base64xml = xml.data.base64;
console.log(base64xml);
res.render('hello.ejs',{ message: base64xml });
},
error:function(httpResponse){
console.error('Error:' + httpResponse.message);
response.error("Failed to parse feed");
res.render('hello.ejs',{ message: httpResponse.message });
}
});
});
app.listen();
I just use promises. This seems to work for me:
Parse.Cloud.httpRequest({
url: 'a-facebook-graph-url'
}).then(function(httpResponse) {
console.log(httpResponse.text);
var xml = module.stringify(httpResponse.data);
var base64xml = xml.data.base64;
res.render('hello',
{
message: base64xml
});
}, function(httpResponse) {
console.error('Request failed with response code ' + httpResponse.status);
});
More info from parse website here

Categories