简体   繁体   English

如何使用 node.js(express) API 调用访问搜索参数并在 React 前端提供服务

[英]How to access search params with node.js(express) API call and served on react front-end

Tech stack - node.js(express) server, react front-end技术栈- node.js(express) 服务器,react 前端

components folder structure组件文件夹结构
--src --src
--components - 成分
--App - 应用程序
--App.js --App.js
--App.css --app.css
--Business - 商业
--Business.js --Business.js
--Business.css --Business.css
--BusinessList --BusinessList
--BusinessList.js --BusinessList.js
--BusinessList.css --BusinessList.css
--SearchBar - 搜索栏
--img --img
--SearchBar.js --SearchBar.js
--SearchBar.css --SearchBar.css
--util --util
--yelp.js --yelp.js

What i want to happen我想发生什么
When a user enters input into "Search Businesses" and enters input into "Where?"当用户在“搜索企业”中输入输入并在“哪里?”中输入输入时and clicks "Lets go button" it should retrieve the category typed in, EX: "Pizza" and location typed in, EX: "Denver"并单击“让我们开始按钮”,它应该检索输入的类别,例如:“披萨”和输入的位置,例如:“丹佛”

In other words a user should be able to "Search Businesses" and enter a location "Where" and filter the results换句话说,用户应该能够“搜索企业”并输入位置“哪里”并过滤结果

How this is working这是如何工作的
On click of the Let's Go button it calls the searchYelp function which is being imported from yelp.js into App.js inside of yelp.js searchYelp function it fetches the endpoint '/api/hello' from the express server thats calling the API.单击 Let's Go 按钮时,它调用从 yelp.js 导入到 App.js 中的 yelp.js searchYelp 函数的 searchYelp 函数,它从调用 API 的快速服务器获取端点“/api/hello”。

Whats happening currently目前正在发生什么
So currently no filtering is happening and when you click the "Let's Go" button it returns a list of random businesses所以目前没有进行过滤,当你点击“Let's Go”按钮时,它会返回一个随机企业列表
I have the filtering code setup i just dont know how to implement it to get it working...我有过滤代码设置,我只是不知道如何实现它以使其正常工作......

Heres the code这是代码

SearchBar.js搜索栏.js

import React from 'react';
import './SearchBar.css';

class SearchBar extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            term: '',
            location: '',
            sortBy: 'best_match'
        }

        this.handleTermChange = this.handleTermChange.bind(this)
        this.handleLocationChange = this.handleLocationChange.bind(this)
        this.handleSearch = this.handleSearch.bind(this)

        this.sortByOptions = {
            'Best Match': 'best_match',
            'Highest Rated': 'rating',
            'Most Reviewed': 'review_count'
        };
    }

    getSortByClass(sortByOption) {
        if (this.state.sortBy === sortByOption) {
            return 'active'
        }
        return ''
    }

    handleSortByChange(sortByOption) {
        this.setState({
            sortBy: sortByOption
        })
    }

    handleTermChange(event) {
        this.setState({
            term: event.target.value
        })
    }

    handleLocationChange(event) {
        this.setState({
            location: event.target.value
        })
    }

    handleSearch(event) {
        this.props.searchYelp(this.state.term, this.state.location, this.state.sortBy)
        event.preventDefault()
    }

    renderSortByOptions() {
        return Object.keys(this.sortByOptions).map(sortByOption => {
            let sortByOptionValue = this.sortByOptions[sortByOption]
            return <li onClick={this.handleSortByChange.bind(this, sortByOptionValue)} className={this.getSortByClass(sortByOptionValue)} key={sortByOptionValue}>{sortByOption}</li>;
        })
    }

    render() {
        return (
            <div className="SearchBar">
                {this.searchYelp}
                <div className="SearchBar-sort-options">
                    <ul>
                        {this.renderSortByOptions()}
                    </ul>
                </div>
                <div className="SearchBar-fields">
                    <input onChange={this.handleTermChange} placeholder="Search Businesses" />
                    <input onChange={this.handleLocationChange} placeholder="Where?" />
                    <button className="SearchBar-submit" onClick={this.handleSearch}>Let's Go</button>
                </div>
            </div>
        )
    }
};

export default SearchBar;

App.js应用程序.js

import React from 'react';
import BusinessList from '../BusinessList/BusinessList';
import SearchBar from '../SearchBar/SearchBar';
import Yelp from '../../util/yelp';
import './App.css';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      businesses: [],
    };

    this.searchYelp = this.searchYelp.bind(this);
  }

  searchYelp(term) {
    Yelp.searchYelp(term).then((businesses) => {
      this.setState({ businesses: businesses })
    })
  }
  render() {
    return (
      <div className="App">
        <SearchBar searchYelp={this.searchYelp} />
        <BusinessList businesses={this.state.businesses} />
      </div>
    )
  }
}

export default App;

Yelp.js Yelp.js

const { default: SearchBar } = require("../components/SearchBar/SearchBar");

const Yelp = {
    searchYelp(term) {
    return fetch('/api/hello/:term')
        .then((response) => {
            console.log(response)
            return response.json()
        }).then((jsonResponse) => {
            console.log(jsonResponse)
            if (jsonResponse.businesses) {
                return jsonResponse.businesses.map((business) => {
                    return {
                        id: business.id,
                        imageSrc: business.image_url,
                        name: business.name,
                        address: business.location.address1,
                        city: business.location.city,
                        state: business.location.state,
                        zipCode: business.location.zip_code,
                        category: business.categories.title,
                        rating: business.rating,
                        reviewCount: business.review_count,
                    }
                })
            }
        })
    }
}

export default Yelp

And the server和服务器
I was trying to filter the term only to test but was unsuccessful, If i could get the term and location working i would be fine with that i think, and leave out sortBy... Server.js我试图过滤该术语只是为了测试但没有成功,如果我能让术语和位置正常工作,我认为我会很好,并省略 sortBy... Server.js

const express = require('express');
const axios = require('axios');
require('dotenv').config();
const cors = require('cors');
const bodyParser = require('body-parser');

const app = express();
app.use(cors());
const port = process.env.PORT || 5000;

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

const apiKey = process.env.APIKEY

app.get('/api/hello/:term', (req, res) => {
    const term = req.params.term
    const config = {
        method: 'get',
        url: 'https://api.yelp.com/v3/businesses/search?term=${term}&location=${location}',
        headers: {
            'Authorization': `Bearer ${apiKey}`
        }
    };

    axios(config)
        .then(function (response) {
            // res.send(JSON.stringify(response.data, null, 2));
            // res.send(term)
            return JSON.stringify(response.data, null, 2)
        }) 
        .then(function (jsonResponse) {
            res.send(jsonResponse)
        }) 
        .catch(function (error) {
            console.log(error);
        });
});

app.listen(port, () => console.log(`Listening on port ${port}`));

Heres a screenshot of the web app这是网络应用程序的屏幕截图
在此处输入图片说明

if you want to use the built-in capability of the yelp location filter, you better express it in your express app (pun intended!):如果你想使用 yelp location过滤器的内置功能,你最好在你的 express 应用程序中表达它(双关语!):

app.get('/api/hello/', (req, res) => {
    // use query instead of params,
    // and destruct location as well
    const {term, location} = req.query
    const config = {
        method: 'get',
        url: 'https://api.yelp.com/v3/businesses/search?term=${term}&location=${location}',
        headers: {
            'Authorization': `Bearer ${apiKey}`
        }
    };
}

... and pass query parameters in the front end: ...并在前端传递查询参数:

const Yelp = {
    // take care to update any existing calls
    // to this function with the location parameter
    searchYelp(term, location) {
        return fetch(`/api/hello?term=${term}&location=${location}`)
        // etc. etc. ...

if you just want to filter it in the front end (not recommended), and the location input will always hold a city name (and you can enforce it) - you're nearly there, all that's left to do is to declare the new function arguments, and filter the result:如果您只想在前端对其进行过滤(不推荐),并且位置输入将始终包含一个城市名称(并且您可以强制执行它)-您就快到了,剩下要做的就是声明新的函数参数,并过滤结果:

function searchYelp(term, location, sortBy) {
  // ...
  this.setState({ businesses: businesses.filter(business => business.city === location) })
  // ...
}

if you still don't want to use yelp API's location , and want a more fuzzy search (ie to be able to feed a general term, like "brooklyn", and output exact info like city, state, zip code etc.), you would have to implement some sort of autocomplete mechanism on the location input, which will involve further calls to some backend service.如果您仍然不想使用 yelp API 的location ,并且想要更模糊的搜索(即能够提供一般术语,如“brooklyn”,并输出准确的信息,如城市、州、邮政编码等),您必须在位置输入上实现某种自动完成机制,这将涉及对某些后端服务的进一步调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM