I am developing an Order Scan web application, and the challenge I'm facing is that, if barcode matches, where I'm going to receive data in my react.js application. I'll be using a barcode scanner device, so can I use this npm package https://www.npmjs.com/package/react-barcode-reader. If so, how to implement it in my react app?
I have searched the web for answers. I couldn't find anything to my specific problem in react.js.
A barcode scanner is simply an input device. Just think of it as a keyboard.
You may receive its inputs via any TextInputs component.
If your barcode scanner is programmed to terminate with "\n", then the TextInput will also trigger onSubmit event.
I would recommend using the React Barcode Scanner NPM package. A simple demonstration is on that site. You can use their Barcode Scanner component:
<BarcodeReader
onError={handleError}
onScan={handleScan}
/>
You can apply that component in where you want the user to perform the scan. You will just need to make a handleScan and handleError function.
Examples:
const [scanData, setScanData] = useState()
const handleScan = (data) => {
setScanData(data)
}
const handleError = (err) => console.error(err)
The data will be stored in the scanData variable. Hope you find this helpful.
This is a very simple example for barcode reading in React, using simple vanilla javascript:
This works using timeframe to detect barcode readings. You can easily change it for endline codes (you won't need the timeout)
import { useEffect, useState } from "react";
import "./App.css";
function App() {
const [barcodeRead, setBarcodeRead] = useState("");
const barcode = {
timing: 1000,
data: "",
};
const barcodeReaded = () => {
if (barcode.data.length > 1) {
setBarcodeRead(barcode.data);
} else {
barcode.data = "";
}
};
let timeout = setTimeout(barcodeReaded, 500);
useEffect(() => {
window.addEventListener("keypress", (e) => {
console.log(e.key);
console.log(e.timeStamp);
if (barcode.data.length === 0 || e.timeStamp - barcode.timing < 200) {
barcode.data += e.key;
barcode.timing = e.timeStamp;
clearTimeout(timeout);
timeout = setTimeout(barcodeReaded, 500);
} else {
barcode.data = "";
}
console.log(barcode);
});
}, []);
return (
<div className="App">
<div>Readed: {barcodeRead}</div>
</div>
);
}
export default App;
Related
Is it possible using laser barcode scanner in expo?
i did something like this , but i cant make it to work.
Basicly im trying to get the scanned data from PDA(android) device , that when i click to scan on PDA i get info to a console log per example to test it ,later on i will need that data to spread to a specific number of inputboxes.
Right now when i clicked on the scan button nothing happens but if i try to use a phone with a camera it works without the click function.
import { Text, View, StyleSheet, Button } from 'react-native';
import { BarCodeScanner } from 'expo-barcode-scanner';
export default function App() {
const [scanned, setScanned] = useState(false);
const handleBarCodeScanned = ({ data }) => {
setScanned(true);
alert(`${data}`);
};
const handleKeyPress = (event) => {
if(event.key === 'Enter'){
handleBarCodeScanned
}
};
return (
<BarCodeScanner
onBarCodeScanned={scanned ? undefined : handleKeyPress}
></BarCodeScanner>
);
}```
I am trying to use Chrome nfc api (WEB NFC) inside of react, so when you open the react page on mobile with nfc enabled and press a button it check to see if nfc scan.
I was reading through the doc and the sample code to do this is,
scanButton.addEventListener("click", async () => {
log("User clicked scan button");
try {
const ndef = new NDEFReader();
await ndef.scan();
log("> Scan started");
ndef.addEventListener("readingerror", () => {
log("Argh! Cannot read data from the NFC tag. Try another one?");
});
ndef.addEventListener("reading", ({ message, serialNumber }) => {
log(`> Serial Number: ${serialNumber}`);
log(`> Records: (${message.records.length})`);
});
} catch (error) {
log("Argh! " + error);
}
});
My react page is currently,
import { Button } from "#material-ui/core";
import React from "react";
const nfcpage = () => {
return (
<>
<Button
id = "scanButton"
>
Press to test NFC
</Button>
</>
);
};
export default nfcpage;
I want the scanButton code to run when the button is pressed. In other words to make scanButton into a function that can be called by my button via onClick{}.
Thank you
I was able to fix this by creating an async function from the sample code and passing that to onClick in the button component
I'm trying to send a text message using expo-sms, the problem is when the sms modal is open to send the message - it immediately closing and the result of SMS.sendSMSAsync is cancelled.
my code is this:
<TouchableOpacity onPress={() => handleSend(contacts, text)}>{...}</TouchableOpacity>
async function handleSend(contacts, text) {
try {
const numbersArr = contacts.map(c => c.number)
while (numbersArr.length > 0) {
const number = numbersArr.pop()
const { result } = await SMS.sendSMSAsync(number, text)
// 'result' here is 'canceled' for each number
}
showMessagesSuccessfullySentMessage()
} catch (e) {
console.error(e)
showSmsSendingProblemError()
}
}
SMS sending is available, of course, I do the check in advanced using useEffect when the component is mounted:
useEffect(() => {
;(async function() {
const isAvailable = await SMS.isAvailableAsync()
setIsSmsAllowed(isAvailable)
})()
}, [])
what am I doing wrong? what did I miss?
Moreover, when I write a brand new app from scratch with the following code, everything works just perfect:
const numbersArr = ['1234', '12345', '123456', '1234567'] // dummy numbers here
export default function App() {
async function handleSend () {
const isAvailable = await SMS.isAvailableAsync()
if (isAvailable) {
while (numbersArr.length > 0) {
const n = numbersArr.pop()
const result = await SMS.sendSMSAsync(n, 'My sample HelloWorld message')
console.log('results', result)
}
} else {
// misfortune... there's no SMS available on this device
}
}
return (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
<StatusBar style="auto" />
<Button title="Send" onPress={handleSend}/>
</View>
)
}
some technical data and versions:
tested on iPhone 11 Pro
"expo": "~36.0.0"
"expo-sms": "~8.0.0"
We don't have any known issues with Expo SMS at the moment. I wrote a small example Snack, you can see it here. I've tested the dialog on both Android and iOS.
If you think this is an issue with Expo, please open an issue at expo/expo.
the problem was that my selected dummy contacts was accidentally created with the wrong phone number field, eventually resulted with number=undefined being called on SMS.sendSMSAsync(undefined, 'My sample HelloWorld message')
Obviously I created those dummy contacts to avoid testing the app on my real contacts...
(sorry for bothering the network)
Opened an issue to expo to discuss the option to throw error or at least a warning in dev stage to warn for undefined/null value being passed to SMS.sendSMSAsync
I've read the doc about React.Suspense, it seems great, but how can I use it while performing an api call, with axios for example?
To be more specific, why this code doesn't work?
export default function Foo(){
const [state, setState] = useState()
useEffect(()=> {
axios.get("url")
.then(res=> setState(res.data))
.catch(_=> setState(null)
}, [])
return (
<Suspense fallback="loading data">
<div>hello {state.name}</div>
</Suspense>
)
}
Thanks!
According to the React documentation, what you are trying to achieve is possible. There is an experimental feature called Concurrent Mode. You can find the implementation details in React documentation.
Link to the Suspense documentation: https://reactjs.org/docs/concurrent-mode-suspense.html
But there is a limitation, you have to use an npm package which leverages this feature. Relay is what is suggested by the React team.
This is the code sandbox link provided in the documentation itself.
https://codesandbox.io/s/frosty-hermann-bztrp
Try something like this:
// fetch data
function fetchSomeData(baseCatUrl) {
let status = "pending";
let result;
let suspender = axios(baseCatUrl).then((res) => {
status = "success";
result = res.data;
}, (e) => {
status = "error";
result = e;
});
return {
read() {
if (status === "pending") {
throw suspender;
} else if (status === "error") {
throw result;
}
else if (status === "success") {
return result;
}
}
}
}
// Component using data
const resource = fetchSomeData(baseCatUrl);
const Component = () => {
return (
<Suspense fallback={<p>Loading...</p>}>
<ChildComponent resource={resource} />
</Suspense>
)
};
Suspense is used to asynchronously load Components, not APIs. It's used to lazily load components imported using React.lazy.
Even if you manage to render your component it'll not make any difference in your case. You'll need it for a different use case
I am developing an app in React js, I'm having an issue to check whether a particular file exists in the directory or not.
Actually I have a header component i.e Header.js and its a common header. But for some clients I have to change the header according to their requirements. I've to do this by making a folder with client's id and then store new header component for that client in that directory. Now I've to check on run time if a header for a specific client exists then show that client's specific header else the common header. I also have to make some other client specific components i.e footer, aside or section etc. for some specific specific clients according to their requirements. But I'm unable to check in react whether a specific component/file exists or not??
You can try to require your file and then depending on the result display the correct component.
const tryRequire = (path) => {
try {
return require(`${path}`);
} catch (err) {
return null;
}
};
Then to use it :
render() {
const Header = tryRequire('yourPath') ? tryRequire('yourPath').default
: DefaultHeader;
return (
<Header />
);
}
There is another way using React.lazy but to do so you will need to create a component that is located at to root of your project (if you are using Create React App it will be placed at ./src/DynamicImport.js).
Here's the logic:
import React, { Suspense, useState, useEffect, lazy } from 'react';
const importCompo = (f, defaultComponentPath) =>
lazy(() =>
import(`./${f}`).catch((err) => {
// Simulate behaviour in Strapi
// Lazy only support default export so there's a trick to do here
when using a library that does not have a default export
// The example here uses the strapi-helper-plugin package
if (defaultComponentPath === 'strapi-helper-plugin') {
return import('strapi-helper-plugin').then((module) => {
const { Button } = module;
return {
// Here's the trick
// I am creating a new component here
default: () => <Button primary>Something</Button>,
};
});
}
return import(`${defaultComponentPath}`);
}),
);
const DynamicImport = ({ filePath, defaultComponentPath, ...rest }) => {
const [module, setModule] = useState(null);
useEffect(() => {
const loadCompo = () => {
const Compo = importCompo(filePath, defaultComponentPath);
setModule(<Compo {...rest} />);
};
loadCompo();
}, []);
return <Suspense fallback="loading">{module}</Suspense>;
};
DynamicImport.defaultProps = {
// defaultComponentPath: './components/DefaultCompo',
defaultComponentPath: 'strapi-helper-plugin',
};
export default DynamicImport;
Then to use it:
const MyCompo = props => {
return (
<DynamicImport
filePath="./components/Foo"
defaultComponentPath="./components/DefaultCompo"
/>
);
};