フリーランス 技術調査ブログ

フリーランス/エンジニア Ruby Python Nodejs Vuejs React Dockerなどの調査技術調査の備忘録

React + Express + YahooAPIでバーコードスキャナーを作成する

はじめに

  • 以前、フロント側でバーコードスキャンを実装したので、読み込んだ時にYahooAPIを利用してバーコード検索して読み込んだ結果を表示する px-wing.hatenablog.com

実装内容

  • Backend側はexpressを利用してAPIをコールして結果をフロントに返す
  • スキャンが完了したら、完了した旨をユーザーに音声で通知する

 コード (express側)

router.get('/product_search', async (req, res, next) =>{
  logger.app.debug(req.query.barcode)
  const result = await axios.get(`https://shopping.yahooapis.jp/ShoppingWebService/V1/json/itemSearch?appid=<あなたのAPIキー>&jan=${req.query.barcode}`)
  .then(res =>{
    return res.data.ResultSet[0].Result[0]
  })
  res.json(result)
})

 コード (front側)

import React , { useState,useEffect } from 'react'
import Quagga from "quagga";
import axios from 'axios'

const BarcodeScan = (props) => {

  const [barcode,setBarcode] = useState("")
  const [product,setProduct] = useState({})

  const barcodeApi = async (barcode) => {
    const result = await axios.get(`https://www.px-wing.com/backend/api/product_search?barcode=${barcode}`)
    .then(res =>{
       const endAnnounce = new SpeechSynthesisUtterance("読み込みました")           
       speechSynthesis.speak(endAnnounce)  
      return setProduct(res.data)
    })
    console.log(result)
  }
  

  const config = {
    inputStream: {
      name : "Live",
      type : "LiveStream",        
      target: '#preview',
      size: 1000,
      singleChannel: false
    },
    locator: {
      patchSize: "medium",
      halfSample: true
    },
    decoder: {
      readers: [{
        format: "ean_reader",
        config: {}
      }]
    },
    numOfWorker: navigator.hardwareConcurrency || 4,
    locate: true,
    src: null
  };

  useEffect(() => {
    Quagga.onDetected(result => {
      if (result !== undefined){
        setBarcode(result.codeResult.code)
      }
    });

    
    Quagga.init(config, function(err) {
        if (err) {
            console.log(err);
            return
        }
        Quagga.start();
    });
  
  },[])

  useEffect(() => {
    console.log(barcode)
    if (barcode){
      Quagga.stop()
      barcodeApi(barcode)
      Quagga.init(config, function(err) {
        if (err) {
            console.log(err);
            return
        }
        Quagga.start();
    });

      }
  },[barcode])

  return (
    <>
      <h2>バーコードスキャナ</h2>
      <hr />
      {barcode !== "" ? `バーコード:${barcode}` : "スキャン中"}
      <hr />
      {
        Object.keys(product).length ?
          <table>
            <tr>
              <td>商品名</td>
              <td><a href={product.Url}>{product.Name}{product._attributes.index}</a></td>
            </tr>
            <tr>
              <td>商品詳細</td>
              <td>{product.Description}</td>
            </tr>
            <tr>
              <td>商品画像</td>
              <td>{product.Image ? <img src={product.Image.Small} /> : '画像はありません'}</td>
            </tr>
            </table>             
          : ''
      }
      <div id="preview"></div>
    </>
  )
}

export default BarcodeScan

デモ画面

  • 何度も読み込みましたと再生されてしまう件はsleepを入れて対応する余地はありそう streamable.com