Why does ReactRouter's Route path ":params" read as "styles.css" in express? - mongodb

I am using Reactrouter in my front end and Express in my back end.
When I am routing with custom parameters which im using for a findbyID fetch for a component, I found
through my error log on express side read the custom param as styles.css.
React Rounter Side:
<Route path="/id/:id" component={Something} />
On Express:
app.get("/id/:id", (req, res) => {
const id = req.params.id;
database.findById(id, (e, found) => {
console.log(id);
if (!e) {
console.log(found);
} else {
console.log(e);
console.log("consult stack overflow");
}
});
});
Error Message:
MongooseError [CastError]: Cast to ObjectId failed for value "styles.css" at path "_id" for model "database"
Why does it do this and how can I fix it?

So as it turns out I have a Link to a styles.css in my index html page. soon as i removed that everything worked the way it should have. So if anyone Is stuggling with this exact same issue later down the line here's hoping this helps you. Check your index.html file for any matching names.

Related

Next.js: Trying to figure out how to consume a third-party Rest API

Context: I do not have a DB, everything I got came from another server's endpoints.
My directory structure looks like:
-components
-pages
--api
(I think every one do something like this)
inside API directory is where my Rest's requisitions are. Everytime some client enters, A token's requisition must be done at get_token.js into API directory, right? Here's the code:
export default async function Token(req, res) {
var formdata = new FormData();
formdata.append("user", "user_name");
formdata.append("password", "my_password");
var requestOptions = {
method: "POST",
body: formdata,
redirect: "follow",
};
await fetch(
"https://endpoint",
requestOptions
)
.then((res) => res.json())
.then((result) => (data = result))
.catch((error) => console.log("error", error));
}
If I access the result directly in localhost:3000/api/token, it returns exactly what I want. At my component's directory I have no idea how to access this fetch() result... If I try to made the request outside the API's directory, it doesn't work at all (the only error message it returns is something like "Fetch fails", with the same code. I've tried to use getStaticProps(). Returns nothing. Tried to use an inside function, async... It fails again. The fetch() only works at API's dir.
the code at the others dirs, are simple as any other "page" + "component" structure...
The code at component's dir:
export default function PageNameComponent(){
return (<div>... </div>) }
and at page's directory I have:
export default class PageName extends React.Component{
render(){
return (
<div>
<MyHeader />
<PageNameComponent/>
<MyFooter />
</div>
);
}
}
Could someone explain how it works? and the best practice to this context?

Mistake in using DOMPurify on the backend to sanitize form data?

I was wondering if it was possible to use DOMPurify to sanitize user input on a form before it is saved to database. Here's what I've got in my routes.js folder for my form post:
.post('/questionForm', (req, res, next) =>{
console.log(req.body);
/*console.log(req.headers);*/
const questions = new QuestionForm({
_id: mongoose.Types.ObjectId(),
price: req.body.price,
seats: req.body.seats,
body_style: req.body.body_style,
personality: req.body.personality,
activity: req.body.activity,
driving: req.body.driving,
priority: req.body.priority
});
var qClean = DOMPurify.sanitize(questions);
//res.redirect(200, path)({
// res: "Message recieved. Check for a response later."
//});
qClean.save()
.then(result => {
//res.redirect(200, '/path')({
// //res: "Message recieved. Check for a response later."
//});
res.status(200).json({
docs:[questions]
});
})
.catch(err => {
console.log(err);
});
});
I also imported the package at the top of the page with
import DOMPurify from 'dompurify';
When I run the server and submit a post request, it throws a 500 error and claims that dompurify.sanitize is not a function. Am I using it in the wrong place, and/or is it even correct to use it in the back end at all?
This might be a bit late, but for others like me happening to run into this use case I found an npm package that seems well suited so far. It's called isomorphic-dompurify.
isomorphic-dompurify
DOMPurify needs a DOM to interact with; usually supplied by the browser. Isomorphic-dompurify feeds DOMPurify another package, "jsdom", as a dependency that acts like a supplementary virtual DOM so DOMPurify knows how to sanitize your input server-side.
In the packages' own words "DOMPurify needs a DOM tree to base on, which is not available in Node by default. To work on the server side, we need a fake DOM to be created and supplied to DOMPurify. It means that DOMPurify initialization logic on server is not the same as on client".
Building on #Seth Lyness's excellent answer --
If you'd rather not add another dependency, you can just use this code before you require DOMPurify. Basically what isometric-dompurify is doing is just creating a jsdom object and putting it in global.window.
const jsdom = require('jsdom');
const {JSDOM} = jsdom;
const {window} = new JSDOM('<!DOCTYPE html>');
global.window = window;

How to access actions in the controller

I'm a newbie trying to learn sails js, please bear with me.
As instructed in a tutorial I tried to set up my controllers and views to show a simple page just to make sure that the routing is working as expected.
So I have a PersonalController.js inside api/controllers folder. This was generated automatically from the generate cli command so I'm sure the location is correct.
Then I create a test view inside views/pages. I named it personal.ejs.
And so I modified my PersonalController to this
module.exports = {
list: function(req, res) {
return res.view('personal');
}
};
I don't know why but I'm getting an error.
I tried to just return json but I still get the same result, 404.
module.exports = {
list: function(req, res) {
return res.json({
todo: 'test'
});
}
};
I know I am missing something, just not sure what it is.

Cannot read property 'getHostNode' of null occurs when I refresh on nested route

I am having two errors when I try to access the elements of a returned object.
errors are : Cannot read property '_id' of undefined
Cannot read property 'getHostNode' of null
This is first part of the code where I extract data from mongoDB into ContactView Component
componentDidMount(){
let contactList = 'http://localhost:5000/v1/contacts';
let callHistory = 'http://localhost:5000/v1/call-history';
axios.all([
axios.get(contactList),
axios.get(callHistory)
])
.then( axios.spread((list, history) => {
console.log(list.data);
console.log(history.data);
this.setState({contactList: list.data, callHistory: history.data});
}))
.catch(function (error) {
console.error(error);
});
}
render() {
return (
<BrowserRouter>
<Switch>
<Route exact path="/contact/:id" component={(props)=> <ContactView contactList={this.state.contactList} id={props.match.params.id} />} />
</Switch>
</BrowserRouter>
);
}
In the ContactView component, I have
contactId(){
const contactList = this.props.contactList;
const contact = _.find(contactList, contact => {return contact._id === contact._id});
this.setState({contact: contact});
console.log(this.state.contact) //works well at all times
console.log(this.state.contact._id) //works initially but returns an error when I refresh on the contact/:id route
}
when I console.log(this.state.contact) I get the object returned to me properly without errors
{_id: "5a232cea94aff40b907fc69b", name: "Dustin Briggs", phone_number: "+185738960158", address: "10 Satin road, Milky-Way 85701, USA"}
but when I try to access the elements in the object or do something like this console.log(this.state.contact._id) I don't get an error navigating from the root to the page but when I refresh on the page an error occurs;
I get both errors
Uncaught TypeError: Cannot read property '_id' of undefined
Uncaught (promise) Cannot read property 'getHostNode' of null
Please I need help to know what I'm doing wrong to fix this bug, which only occurs when I refresh on the contact/:id route
"I don't get an error navigating from the root to the page but when I refresh on the page an error occurs;"
This is happening because when you are in root, on componentDidMount you got the data and then you are going to the page with data. But when you are directly going to the page, page is trying to access the data while it is still being fetched. So this intermediate state is causing error.
To avoid these error you can sanitize your data. As in before extracting data check if the key even defined or not. For example.
const contactList = this.props.contactList || [];
const contact = _.find(contactList, contact => {
return contact && contact._id === contact._id
});

Backbone.js with MongoDB passing req.params into exports functions

I am trying to send a request parameter through to an 'exports' method for a mongodb find in an express.js, backbone.js application. I am having a difficult
time getting the parameters to pass through to mongodb and with '#'.
The breakage is the passing of parameters into the exported mongodb function.
Here is the flow of data:
First the request is successfully routed to the 'upcoming' function:
"upcoming/uni/:uni" : "upcoming",
It flows on to the 'upcoming' function without a problem.
upcoming: function(uni) {
console.log("uni: "+uni);
pag.reset();
console.log("Hit upcoming list target");
setCollectionType('upcoming');
var upcomingCourses = buildCollection();
// ------------------------------------------------------------------------
// here is the problem how do I pass the parameter value through the fetch?
// Although it may also have to do with '#' please read on.
// ------------------------------------------------------------------------
upcomingCourses.fetch({success: function(){
$("#content").html(new ListView({model: upcomingCourses, page: 1}).el);
}});
this.headerView.selectMenuItem('home-menu');
},
The routing for the mongo methods is:
app.get('/upcoming/uni/:uni', mongomod.findUpcoming);
So the following method is exported from the mongodb js file and is executed reliable. However the req.params are not passed through.
Interspersed in the code I have described its' runtime behaviour:
exports.findUpcoming = function(req, res) {
console.log("university", req.params.uni); // This consistently is unpopulated
var uni = req.params.uni;
console.log("Size: "+req.params.length); // This will always be 0
for (var i=0; i < req.params.length; i++) {
console.log("Parameters: "+req.params[i]);
}
db.collection('upcoming', function(err, collection) {
if (typeof uni === 'undefined') {
console.log("The value is undefined");
uni = "Princeton University"; // here we add a string to test it it will work.
}
collection.find({university:uni}).toArray(function(err, items) {
if (err) {
console.log("Error: "+err);
} else {
console.log("No Error");
console.log("Count: "+items.length);
console.log(items[0]['university']);
res.send(items);
}
});
});
};
On additional and important note:
The url, in a working, runtime environment would be:
http://localhost:3000/#upcoming/uni/Exploratorium
This one fails, but the following URL will work in passing the params through these functions however it returns the JSON to the screen rather then
the rendered version:
http://localhost:3000/upcoming/uni/Exploratorium
The problem could be a miss understanding of # and templates. Please, if you see the error enlightenment would be greatly appreciated.
Nothing after the # gets passed to the server. See How to get hash in a server side language? or https://stackoverflow.com/a/318581/711902.
I found a solution to the problem of passing the parameters from the client side to the server side. By changing the url of the collection the parameters will be passed to the server side:
upcomingCourses.url = "/upcoming/uni/"+uni; // <-- here's the ticket where uni is param
upcomingCourses.fetch({success: function(){
$("#content").html(new ListView({model: upcomingCourses, page: 1}).el);
}});
This can be made more elegant but it is a way to pass the parameters on to the server.
Thanks