【发布时间】:2019-07-14 06:03:02
【问题描述】:
我正在尝试为我的 React 应用访问我的 MongoDB 的两个集合。我已经构建了两个 API_URL:
const API_URL = window.location.hostname === 'localhost' ? 'http://localhost:5000/api/v1/Sessions' : 'production-url-here'
const API_URL1 = window.location.hostname === 'localhost' ? 'http://localhost:5000/api/v1/members' : 'production-url-here'
当我将 url 放入浏览器时,会话集合会返回原始数据,但成员 URL 会返回“未找到”消息。
我已经为我的成员集合镜像了会话集合的服务器和客户端代码,但我不确定问题是什么。
这是 members.js 的代码:
const express = require('express');
const Joi = require("joi");
const db = require('../db');
const members = db.get('members');
//Defining the schema for the backend.
const schema1 = Joi.object().keys({
name: Joi.string().min(1).max(100).required(),
bio: Joi.string().min(1).max(500).required(),
latitude: Joi.number().required(),
longitude: Joi.number().required()
});
const router = express.Router();
//Gets all sessions that are found within the DB.
router.get('/', (req, res) => {
members
.find()
.then(allmembers =>{
res.json(allmembers);
});
});
module.exports = router;
这是 Sessions.js 的代码:
const express = require('express');
const Joi = require("joi");
const db = require('../db');
const Sessions = db.get('Sessions');
//Defining the schema for the backend.
const schema = Joi.object().keys({
event: Joi.string().min(1).max(100).required(),
venue: Joi.string().min(1).max(500).required(),
address: Joi.string().min(1).max(100).required(),
dtstart: Joi.string().required(),
dtend: Joi.string().required(),
latitude: Joi.number().required(),
longitude: Joi.number().required()
});
const router = express.Router();
//Gets all sessions that are found within the DB.
router.get('/', (req, res) => {
Sessions
.find()
.then(allSessions =>{
res.json(allSessions);
});
});
//POST for when no errors are produced.
router.post('/', (req, res, next) => {
const result = Joi.validate(req.body, schema);
if (result.error == null) {
//Removes the need to write eg) req.body.name below.
const { event, venue, address, latitude, longitude, dtstart, dtend,} = req.body;
const Session = {
event,
venue,
address,
dtstart,
dtend,
latitude,
longitude,
date: new Date()
};
Sessions.insert(Session).then(insertedMessage => {
res.json(insertedMessage);
});
}
else {
next(result.error);
}
});
module.exports = router;
前端代码:
import React, { Component } from 'react';
import './App.css';
import L from 'leaflet';
import Joi from 'joi';
//import only modules needed or error.
import { Map, TileLayer, Marker, Popup } from 'react-leaflet';
import { Card, CardTitle, CardText } from 'reactstrap';
import {Form, FormGroup, Label, Input } from 'reactstrap';
import { Button } from 'reactstrap';
import Chart from './components/Chart';
var myIcon = L.icon({
iconUrl: 'https://purepng.com/public/uploads/large/purepng.com-harpharpstringedsoundboardfingersmodern-1421526538276nepuu.png',
iconSize: [25, 51],
iconAnchor: [12.5, 51],
popupAnchor: [0, -51],
draggable: true,
});
//Joi creates the schema for validation
const schema = Joi.object().keys({
event: Joi.string().min(1).max(100).required(),
venue: Joi.string().min(1).max(500).required(),
address: Joi.string().min(1).max(100).required(),
dtstart: Joi.string().required(),
dtend: Joi.string().required()
});
const schema1 = Joi.object().keys({
name: Joi.string().min(1).max(100).required(),
bio: Joi.string().min(1).max(500).required(),
latitude: Joi.number().required(),
longitude: Joi.number().required()
});
//URL declaration, if hostname is localhost, request backend. otherwise URL.
const API_URL = window.location.hostname === 'localhost' ? 'http://localhost:5000/api/v1/Sessions' : 'production-url-here'
const API_URL1 = window.location.hostname === 'localhost' ? 'http://localhost:5000/api/v1/members' : 'production-url-here'
class App extends Component {
state = {
location: {
lat: 51.505,
lng: -0.09,
},
UserslocationFound: false,
zoom: 12,
/* Monitors the state of the users inputs (detects changes). */
UsersSession: {
event: '',
venue: '',
address: '',
dtstart: '',
dtend: ''
},
Sessions: [],
members: []
}
componentDidMount() {
//Grabs the markers from the Thesession API to be displayed.
fetch(API_URL)
.then(res => res.json())
.then(Sessions => {
this.setState({
Sessions
});
});
fetch(API_URL1)
.then(res => res.json())
.then(members => {
this.setState({
members
});
});
/*Asks user for location via google alert. */
navigator.geolocation.getCurrentPosition((position) => {
this.setState({
location: {
lat: position.coords.latitude,
lng: position.coords.longitude
},
UserslocationFound: true,
zoom: 15,
draggable: true
});
}, () => {
console.log("Location not given ????");
fetch('https://ipapi.co/json')
.then(res => res.json())
.then(location => {
console.log(location);
this.setState({
location: {
lat: location.latitude,
lng: location.longitude
},
UserslocationFound: true,
zoom: 15
});
});
});
}
formSubmitted = (event) => {
/* prevents the page from refreshing on submit. */
event.preventDefault();
console.log(this.state.UsersSession);
const UsersSession = {
event: this.state.UsersSession.event,
venue: this.state.UsersSession.venue,
address: this.state.UsersSession.address,
dtstart: this.state.UsersSession.dtstart,
dtend: this.state.UsersSession.dtend
};
//importing Joi to get the result through validation of the inputs with the schema.
const result = Joi.validate(UsersSession, schema);
if(!result.error) {
//fetching against API_URL
fetch(API_URL, {
method: 'POST',
headers: {
'content-type': 'application/json',
},
body: JSON.stringify({
...UsersSession,
latitude: this.state.location.lat,
longitude: this.state.location.lng,
})
}).then(res => res.json())
.then(Sessions => {
console.log(Sessions)
});
}
}
/*Updates the state on UsersSession */
valueChanged = (event) => {
/*declaring event.target as it throws errors in chrome */
const { name,value } = event.target;
/*Sets usersSession to be the value defined in inputs */
this.setState((prevState) => ({
UsersSession: {
...prevState.UsersSession,
[name]: value
}
}))
}
//Sharing of code between React components
render() {
const position = [this.state.location.lat, this.state.location.lng]
return (
<div className ="map">
<Map className ="map" center={position} zoom={this.state.zoom}>
/* tile imported to use over leafletjs*/
<TileLayer
attribution='&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
/* displays marker for when users location is given/found */
{ this.state.UserslocationFound ?
<Marker
position={position}
icon={myIcon}>
</Marker> : ''
}
{this.state.Sessions.map(UsersSession => (
<Marker
position={[UsersSession.latitude, UsersSession.longitude]}
icon={myIcon} >
<Popup>
<em>{UsersSession.event}, </em>
{UsersSession.venue} {'\n'}
<Button color="primary" size="sm">More info</Button>
<Chart/>
</Popup>
</Marker>
))}
{this.state.members.map(Users => (
<Marker
position={[Users.latitude, Users.longitude]}
icon={myIcon} >
<Popup>
<em>{Users.name}, </em>
{Users.bio} {'\n'}
<Button color="primary" size="sm">More info</Button>
<Chart/>
</Popup>
</Marker>
))}
</Map>
<Card body className="message-form">
<CardTitle>Welcome to TradMap!</CardTitle>
<CardText>Please input the details of your Session below.</CardText>
<Form onSubmit={this.formSubmitted}>
<FormGroup>
<Label for="name">Session Title</Label>
<Input
/*when the state changes */
onChange={this.valueChanged}
type="text"
name="event"
id="event"
placeholder="..." />
<Label for="startDate">Start Date</Label>
<Input
onChange={this.valueChanged}
type="date"
name="dtstart"
id="dtstart" />
<Label for="EndDate"> End Date </Label>
<Input
onChange={this.valueChanged}
type="date"
name="dtend"
id="dtend" />
<Label for="venue">Session Venue</Label>
<Input
onChange={this.valueChanged}
type="textarea"
name="venue"
id="venue"
placeholder="..." />
<Label for="Address">Session Address</Label>
<Input
onChange={this.valueChanged}
type="textarea"
name="address"
id="address"
placeholder="..." />
</FormGroup>
<Button type ="submit" color="info" disabled={!this.state.UserslocationFound}>submit</Button>
</Form>
</Card>
</div>
);
}
}
export default App;
【问题讨论】:
-
您如何/在哪里使用和整理从
members.js和Sessions.js导出的内容? -
作为一个反应应用程序,它们呈现在我的 app.js 文件夹中。当我将 API_URL1 更改为映射到 Sessions 集合时,代码编译并显示地图,但返回的数据不准确。这个问题似乎指向成员的实际目录,因为我无法通过浏览器或代码访问它。
-
我实际上认为这是一个 React 应用程序这一事实并不重要,因为这是一个前端问题。我相信您在原始问题中输入的所有代码都是后端代码(更具体地说,
express-related)。你在哪里require('./members.js')和require('./Sessions.js'),你如何使用该代码?我怀疑您在某处有类似app.use(Sessions)的行,但不是app.use(members)(其中Sessions和members指的是每个导出的路由器)。 -
我将编辑问题以包含我的前端代码。这可能更能说明我的问题。在我的两个后端文件中,我需要数据库,然后使用 db.get('Sessions') 来获取集合。然后我在它从后端传递到前端后再次使用它(参见上面的代码)
-
您是在为
localhost还是为生产服务器测试这个?我看到了你的前端代码,但我仍然认为这是一个后端问题(鉴于后端控制是否发送404 Not Found)。或者,也许我只是误解了眼前的问题¯\_(ツ)_/¯