Reputation: 4610
I am making a Web App using React 0.14, nodejs, expressjs and mongodb. The app is a URL shortener. When a user enters a URL I generate a shorter URl. I am running it on the following server: http://localhost:3000
Eg. Input: http://test.com Output: http://localhost:3000/xyz
Where localhost:3000 is my host and xyz is a random code that I generate and save in the database for the the URL that was given as input. Till now I am able to generate the shortened URL, but when I try to hit that URL by pasting in the browser, I get an error of react-router saying : Warning: [react-router] Location "/xyz" did not match any routes.
How can I make the get call here? Because the component is not yet mounted and there is no route for the same. Here are my files:
server.js
var express = require('express')
var mongoose = require('mongoose')
var path = require('path')
var bodyParser = require("body-parser");
var app = express()
var port = process.env.PORT || 3000
//controllers
var urlController = require("./controllers/urlController");
/*
To serve static files such as images, CSS files, and JavaScript files, use the express.static built-in middleware function in Express.
*/
//Express request pipeline
app.use(express.static(path.join(__dirname,"../client")))
app.use(bodyParser.json())
app.use("/api", urlController);
/*
Your server must be ready to handle real URLs. When the app first loads at / it will probably work, but as the user navigates around and then hits refresh at /dashboard your web server will get a request to /dashboard. You will need it to handle that URL and include your JavaScript application in the response.
*/
app.get('*', function (request, response){
response.sendFile(path.resolve(__dirname, '../client', 'index.html'))
})
app.listen(port, function () {
console.log('Example app listening on port 3000!')
});
// Connect to our mongo database
mongoose.connect('mongodb://localhost/shortUrl');
/*var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
console.log("mongo connected")
});*/
urlcontroller.js
var router = require("express").Router();
var Utility = require("../utility");
var Url = require("../data/url-schema");
router.route("/urls").post(addUrl).get(getUrl);
function addUrl(req, res) {
/*
Checks if the requested url already exists in the databse.
*/
Url.findOne({longUrl:req.body.longUrl}, function(err, data) {
if (err)
res.send(err);
/*
If the requested url already exits in the database then return that particular data
*/
else if(data) {
console.log("already exists",data)
res.send("http://localhost:3000/"+data.code);
} else {
var url = new Url({
code : Utility.randomString(6,"abcdefghijklm"),
longUrl : req.body.longUrl
});
console.log("in last else data created",url)
/*
If the requested url doesn't exist in the database then save the data in the database
*/
url.save(function (err, data) {
console.log(data)
if (err)
res.send(err);
else
res.send("http://localhost:3000/"+data.code);
});
//res.send("http://localhost/",data.code)
}
});
}
function getUrl(req, res) {
console.log("url--->",req.query.query)
var reg = req.query.query.split('/')
console.log("reg", reg)
//var reg =
Url.findOne({code:reg[3]}, function(err, data){
//res.send(data.longUrl)
console.log("data", data)
if(data)
res.redirect(302, data.longUrl);
//res.send(data.longUrl)
});
}
module.exports = router;
index.js
"use strict";
import React from 'react'
import { render } from 'react-dom'
import { Router, Route, Link, browserHistory } from 'react-router'
//loading jquery
//--------------------------------Isssueee------------------------------
/*import jQuery from 'jquery';
$ = jQuery
*/
//--------------------------------Isssueee------------------------------
/*Require own custom files*/
import App from './app';
import About from './about';
import Dashboard from './dashboard';
import '../css/style.css';
/*Require Bootstrap*/
import '../css/libs/bootstrap.min.css';
import './libs/bootstrap.min.js'
render((
<Router history={browserHistory}>
<Route path="/" component={App}>
<Route path="about" component={About}/>
<Route path="dashboard" component={Dashboard}/>
</Route>
</Router>
), document.getElementById('app'))
dashboard.js
"use strict"
import React from 'react'
import ReactDOM from 'react-dom'
import * as rest from './rest'
import * as utility from './utility'
import { Router, Route, Link, browserHistory } from 'react-router'
class Dashboard extends React.Component {
constructor(props) { //Read
super(props); //Doubt
this.state = {
msg : '',
url : ''
};
}
componentWillMount() {
//utility.extractCode(window.location);
console.log(window.location)
// console.log("loc----",str)
}
setMsg(msg) {
this.setState({
msg : msg
})
}
shortenURL() {
var self = this;
/*
* ReactDOM.findDOMNode(this.refs.Url) - bind is used on the click event of button since es6 doesnot give autobinding as in React.createClass()
*/
let longUrl = ReactDOM.findDOMNode(this.refs.Url).value.trim();
if(longUrl !== ""){
if(utility.validateUrl(longUrl)){
this.setMsg("")
rest.addUrl(longUrl)
.then(function(data, error){
self.setState({
url: data.entity
})
});
}
else {
this.setMsg("URL not valid")
}
} else {
this.setMsg("Please enter a URL")
}
// rest.getUrl(window.location.href)
// .then(function(data){
// console.log("in return data", data)
// //Router.transitionTo(data.entity)
// })
}
render() {
return (
<div className="container">
<form>
<div className="create-board">
<div className="board-header">
<h3 className="board-header-h3">URL Shortener</h3>
</div>
<div className="control-group txt-control">
<div className="form-group">
<label className="control-label" htmlFor="inputURL">Enter your long URL here</label>
<input type="text" ref="Url" className="form-control" placeholder="Enter Your Long URL here"></input>
</div>
<div className="control-group but-control">
<div className="controls">
<button className="btn btn-info" type="button" onClick={this.shortenURL.bind(this)}>Shorten</button>
</div>
</div>
<label>{this.state.msg}</label>
<div><a href={this.state.url} target="_blank">{this.state.url}</a></div>
</div>
</div>
</form>
</div>
)
}
}
export default Dashboard;
rest.js
"use strict";
import Rest from 'rest'
import mime from 'rest/interceptor/mime'
import errorCode from 'rest/interceptor/errorCode'
var config = require('../config.json')
var client = Rest.wrap(mime, {
mime: 'application/json'
})
.wrap(errorCode, {
code: 400
});
export function addUrl(url) {
let postObjects = {
path : config.path,
method : "POST",
entity : {
longUrl : url
},
headers : {
"crossDomain": true,
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "X-Requested-With"
},
params :{}
}
return client(postObjects)
}
export function getUrl(location) {
console.log("location-------->",location)
let postObjects = {
path : config.path,
method : "GET",
entity : {
location : location
},
headers : {
"crossDomain": true,
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "X-Requested-With"
},
params :{
query: location
}
}
return client(postObjects)
}
Upvotes: 1
Views: 2887
Reputation: 47172
As I understand you want to be able to access /xyz
on your Node server and not let React Router handle that path for you?
If so, you need to specify the handler on your server and place it before your catch all route.
app.get('/xyz', () => {});
app.get("*", () => {});
Upvotes: 1