【问题标题】:Connecting to multiple collections in MongoDB连接到 MongoDB 中的多个集合
【发布时间】: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='&amp;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.jsSessions.js 导出的内容?
  • 作为一个反应应用程序,它们呈现在我的 app.js 文件夹中。当我将 API_URL1 更改为映射到 Sessions 集合时,代码编译并显示地图,但返回的数据不准确。这个问题似乎指向成员的实际目录,因为我无法通过浏览器或代码访问它。
  • 我实际上认为这是一个 React 应用程序这一事实并不重要,因为这是一个前端问题。我相信您在原始问题中输入的所有代码都是后端代码(更具体地说,express-related)。你在哪里require('./members.js')require('./Sessions.js'),你如何使用该代码?我怀疑您在某处有类似app.use(Sessions) 的行,但不是app.use(members)(其中Sessionsmembers 指的是每个导出的路由器)。
  • 我将编辑问题以包含我的前端代码。这可能更能说明我的问题。在我的两个后端文件中,我需要数据库,然后使用 db.get('Sessions') 来获取集合。然后我在它从后端传递到前端后再次使用它(参见上面的代码)
  • 您是在为localhost 还是为生产服务器测试这个?我看到了你的前端代码,但我仍然认为这是一个后端问题(鉴于后端控制是否发送404 Not Found)。或者,也许我只是误解了眼前的问题¯\_(ツ)_/¯

标签: node.js reactjs mongodb


【解决方案1】:

问题是在服务器端引用成员集合。我没有在 api 目录的 index.js 文件中引用它:

const Members = require('./Members');

router.use('/Members', Members);

这允许我的集合在我的前端被引用并通过 localhost 访问。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-17
    • 2021-02-11
    • 2023-03-28
    • 2020-08-24
    • 2022-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多