DEV Community

Cover image for Expo Barcode Scanner
Late Night Coder
Late Night Coder

Posted on

1

Expo Barcode Scanner

Before we start we will update our node, npm and expo cli. Just to use all the latest features. Now create a new expo project. Choose the project with everything previously setup. We choose this app to get quickly started.

nvm use 12 // install version 12 - latest@2019  
npm install -g expo-cli // install expo cli globally  
expo init // create a project  
// choose the javascript project with navigation setup
Enter fullscreen mode Exit fullscreen mode

Final product demo

Scanner Screen

In the app, as I am using the minimal setup project I am using the default HomeScreen as ScannerScreen. We are using a React class component you may simply use functional components with hooks for state management.

The Scanner screen is a class-based component. The state has two important properties one hasCameraPermissions for if the screen has permission to access the camera and the second property isisScanned for if something has been scanned or not. Initially, the state of ScannerScreen for hasCameraPermissions is null. Null means that we are requesting for permission. And state isScanned is false means nothing is scanned as of now.

As the scanner requires camera permission thus we need to ask for camera permission from the user. 

Permission is an asynchronous task and we must ask for permission as soon as this component is mounted so componentDidMount seems like a good place to start. Note Permission asking is asynchronous so we have to make componentDidMount a async function. If Camera permission is given then hasCameraPermissions is set to true and we may successfully render our barcode scanner and open camera else if permission is declined *hasCameraPermissions* is set to false and we render declined permission message.

Next, we have a function for handling a successfully scanned barcode. If the bar code is scanned this function will be called. Our function *handleBarCodeScanned* is passed as callback to *onBarCodeScanned* prop on *BarCodeScanner* component. In *handleBarCodeScanned* function we receive a scan object as an argument which has two important properties, one is the *type* which means what type of bar code was scanned and the other is *data* which is the encrypted data in our barcode. We will destructure these properties as others are irrelevant to us. In our case of *handleBarCodeScanned* function, we are just navigating to the *DecodeScreen* passing code data as params. The DecodeScreen then displays the data.

import React from 'react';


import { Container, Spinner, TextH3 } from "../UI";

import * as Permissions from 'expo-permissions';

import { BarCodeScanner } from 'expo-barcode-scanner';

import {window} from "../constants/Layout";

class ScannerScreen extends React.Component{
  static navigationOptions = {
    header: null
  }
  // Component State
  state = {
    hasCameraPermission: null, // if app has permissions to acess camera
    isScanned: false // scanned
  }
  async componentDidMount() {
    // ask for camera permission
    const { status } = await Permissions.askAsync(Permissions.CAMERA);
    console.log(status);
    this.setState({ hasCameraPermission: status === "granted" ? true : false });
  }


  handleBarCodeScanned = ({ type, data }) => {
      // Do something here
      this.props.navigation.navigate('Decode', {
        data: data 
      });
  }
  render(){
    const { hasCameraPermission, isScanned } = this.state;
    if(hasCameraPermission === null){
      // requesting permission
      return (
        <Spinner />
      );
    }
    if(hasCameraPermission === false){
        //permission denied
      return ( 
        <Container>
         <TextH3>Please grant Camera permission</TextH3>
        </Container> 
      )
    }
    if(hasCameraPermission === true && !isScanned && this.props.navigation.isFocused() ){
      // we have permission and this screen is under focus
      return <Container style = {{
        flex: 1,
        flexDirection: 'column',
        justifyContent: 'center',
        alignItems: 'center'

      }}>
        <TextH3>Scan code inside window</TextH3>
        <BarCodeScanner
          onBarCodeScanned = { isScanned ? undefined : this.handleBarCodeScanned }
          style = {{
            height:  window.height / 2,
            width: window.height,
          }}
        >
        </BarCodeScanner>
      </Container>
    }
    else{
      return <Spinner />;
    }
  }
}
export default ScannerScreen;
Enter fullscreen mode Exit fullscreen mode

Github Repo: vtechguys/medium/under folder RN_bar_code_scanner

SurveyJS custom survey software

Build Your Own Forms without Manual Coding

SurveyJS UI libraries let you build a JSON-based form management system that integrates with any backend, giving you full control over your data with no user limits. Includes support for custom question types, skip logic, an integrated CSS editor, PDF export, real-time analytics, and more.

Learn more

Top comments (2)

Collapse
 
bevis profile image
Bevis

No preview image, and example code.

Why we need to read your source code? please do not waste our time.

Collapse
 
bclonan profile image
Bradley Morgan Clonan

I support this message. I saw your source, read the article cause I figured it was going to show me what it looks like. Now I can't choose to copy paste your code example in my prod deploy. Even though the article was useful, and sample good.

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

AWS GenAI LIVE!

GenAI LIVE! is a dynamic live-streamed show exploring how AWS and our partners are helping organizations unlock real value with generative AI.

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️