首页 > 解决方案 > 如何使用 node.js(express) API 调用访问搜索参数并在反应前端提供服务

问题描述

技术栈- node.js(express) 服务器,react 前端

组件文件夹结构

|__src
|  |__components
|     |__App
|     |   |__App.js
|     |   |__App.css
|     |__Business
|     |   |__Business.js
|     |   |__Business.css
|     |__BusinessList
|     |   |__BusinessList.js
|     |   |__BusinessList.css
|     |__SearchBar
|         |__img
|         |__SearchBar.js
|        |__SearchBar.css
|__util
   |__yelp.js


当用户在“搜索业务”中输入输入并在“在哪里?”中输入输入时,我想要发生什么 并单击“Let's go button”,它应该检索输入的类别,例如:“Pizza”和输入的位置,例如:“Denver”

换句话说,用户应该能够“搜索企业”并输入位置“Where " 并过滤结果

这是如何工作
的 点击 Let's Go 按钮,它调用 searchYelp 函数,该函数从 yelp.js 导入到 yelp.js 内部的 App.js 中 searchYelp 函数它获取端点 '/api/ hello' 来自调用 API 的快速服务器。

目前发生了什么
所以目前没有过滤发生,当你点击“Let's Go”按钮时,它会返回一个随机业务列表
我有过滤代码设置我只是不知道如何实现它来让它工作......

继承人编码

搜索栏.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;

应用程序.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

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

我试图过滤该术语仅用于测试但未成功的服务器
,如果我可以使术语和位置正常工作,我认为会很好,并省略 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}`));

这是网络应用程序的屏幕截图
在此处输入图像描述

标签: javascriptnode.jsreactjsapiexpress

解决方案


如果您想使用 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}`
        }
    };
}

...并在前端传递查询参数:

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. ...

如果您只想在前端过滤它(不推荐),并且位置输入将始终包含一个城市名称(并且您可以强制执行它) - 您快到了,剩下要做的就是声明新的函数参数,并过滤结果:

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

如果您仍然不想使用 yelp API location,并且想要更模糊的搜索(即能够提供通用术语,例如“布鲁克林”,并输出准确的信息,例如城市、州、邮政编码等),您必须在位置输入上实现某种自动完成机制,这将涉及对某些后端服务的进一步调用。


推荐阅读