はじめに
- 駅JPのデータを利用して駅検索機能を作成する
- バックエンド側でMySQLに登録されている駅JPのデータをjsonで返す
- フロント側でバックエンド側のURLへアクセスしてjson形式でデータを取得してreact-selectで実装する
過去の記事をベースに実装
px-wing.hatenablog.com
px-wing.hatenablog.com
px-wing.hatenablog.com
px-wing.hatenablog.com
バックエンド 実装
router.get('/stations', async (req, res, next) =>{
db.stations.findAll({
attributes: ['station_cd', 'station_name','lon','lat'],
where: Object.keys(req.query).length > 0 ? req.query : {line_cd: 0},
}).then((stations)=>{
res.json(stations)
});
})
router.get('/lines', async (req, res, next) => {
db.companies.findAll({
where: Object.keys(req.query).length > 0 ? req.query : {company_cd: 0},
include: [{
model: db.lines,
attributes: ['line_cd', 'line_name'],
required: true
}]
}).then((lines)=>{
res.json(lines)
});
})
router.get('/companies', async (req, res, next) =>{
db.companies.findAll({
attributes: ['company_cd', 'company_name'],
}).then((companies)=>{
res.json(companies)
});
})
フロント 実装
鉄道会社プルダウン
import React,{useState, useEffect} from 'react'
import Select from 'react-select'
import axios from 'axios'
import Lines from './Lines'
const Companies = () =>{
const [companies, setCompanies] = useState([]);
const [companyCd, setCompanyCd] = useState(0);
const [companyName, setCompanyName] = useState('鉄道会社を選択して下さい');
const getCmmpanies = async (barcode) => {
const result = await axios.get(`<Your Web Site URL>/backend/api/companies`)
.then(res => {
const companies = res.data.map(companie => {
return { value: companie.company_cd, label: companie.company_name }
});
setCompanies(companies)
})
}
useEffect(() => {
getCmmpanies();
},[]);
const changeCompany = (e) =>{
setCompanyCd(e.value)
setCompanyName(e.label)
}
return (
<>
<h4>駅検索</h4>
<Select options={companies} onChange={changeCompany} value={{ value: companyCd, label: companyName }}/>
{companyCd ? <Lines companyCd={companyCd}/> : ''}
</>
)
}
export default Companies
路線プルダウン
import React,{useState, useEffect} from 'react'
import Select from 'react-select'
import axios from 'axios'
import Stations from './Stations'
const Lines = (props) =>{
const [lines, setLines] = useState([]);
const [companyCd, setCompanyCd] = useState(0);
const [lineCd, setLineCd] = useState(0);
const [lineName, setLineName] = useState('');
const getLines = async (companyCd) => {
const result = await axios.get(`https://<Your Web Site URL>/backend/api/lines?company_cd=${companyCd}`)
.then(res => {
if (res.data.length > 0){
const lines = res.data[0].lines.map(line => {
return { value: line.line_cd, label: line.line_name }
})
setLines(lines)
setLineCd(0)
}
})
}
useEffect(() => {
getLines(props.companyCd);
},[]);
useEffect(() => {
if (props.companyCd !== companyCd){
setCompanyCd(props.companyCd)
getLines(props.companyCd)
setLineCd(0)
setLineName('路線を選択してください')
}
});
const changeLine = (e) =>{
setLineCd(e.value)
setLineName(e.label)
}
return (
<>
<Select options={lines} onChange={changeLine} value={{ value: lineCd, label: lineName }}/>
{lineCd > 0 ? <Stations lineCd={lineCd}/> : ''}
</>
)
}
export default Lines
駅一覧
import React,{useState, useEffect} from 'react'
import axios from 'axios'
const Stations = (props) =>{
const [stations, setStations] = useState([])
const [lineCd, setLineCd] = useState(0)
const getStatons = async (lineCd) => {
const result = await axios.get(`https://<Your Web Site URL>/backend/api/stations?line_cd=${lineCd}`)
.then(res => {
if (res.data.length > 0){
setStations(res.data)
}
})
}
useEffect(() => {
getStatons(props.lineCd)
},[]);
useEffect(() => {
console.log(`${props.lineCd} ${lineCd}`)
if (props.lineCd !== lineCd){
setLineCd(props.lineCd)
getStatons(props.lineCd)
}
});
return (
<>
<h3>{stations ? '駅一覧' : ''}</h3>
<ul>
{stations ?
stations.map(station => {
console.log(station)
return (
<li>
{station.station_name}
</li>
);
}) :
''
}
</ul>
</>
)
}
export default Stations
実装結果
streamable.com