How can I access a public property from Livewire 3 to the corresponding blade if I am using QuaggaJS. I can't use it like this : {{ $barcode }}. I believe that I can't use QuaggaJS and Livewire 3 together. What do you think?
I have a route that display me the blade of TicketScannerComponent.
Route::get('/scan-the-ticket', TicketScannerComponent::class)->name('scan.ticket');
I will show you the blade: ticket-scanner-component.blade.php
{{-- to be moved in app.css --}}
<style>
#barcode-scanner video {
width: 100% !important;
}
</style>
<div>
<div class="fixed top-0 left-0 w-screen h-screen bg-gray-100 flex items-center justify-center">
<div id="barcode-scanner" class="h-full w-full relative">
<!-- Overlay text -->
<div id="overlay-text" class="absolute inset-0 flex justify-center items-center bg-opacity-50 text-white text-lg font-bold">
Scan barcode here {{ $barcode }}
</div>
</div>
<!-- Include the library -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/quagga/0.12.1/quagga.min.js"></script>
</div>
</div>
<script>
{{--https://serratus.github.io/quaggaJS/--}}
// Initialize Quagga
Quagga.init({
inputStream: {
name: "Live",
type: "LiveStream",
target: document.querySelector("#barcode-scanner")
},
decoder: {
readers: ["upc_reader"] // Use the UPC-A reader
}
}, function(err) {
if (err) {
console.error("Error initializing Quagga:", err);
return;
}
console.log("Initialization finished. Ready to start");
Quagga.start();
});
// Listen for barcode detection
Quagga.onDetected(function(result) {
console.log("Barcode detected and read successfully:", result);
// Handle the detected barcode here
alert("UPC-A Barcode detected: " + result.codeResult.code);
sendBarcodeData(result.codeResult.code);
Quagga.stop(); // Stop scanning after a barcode is detected
});
// Function to send barcode data to the backend
function sendBarcodeData(barcode) {
var csrfToken = document.head.querySelector('meta[name="csrf-token"]').content;
// Make an AJAX request to the Laravel route
var xhr = new XMLHttpRequest();
xhr.open("POST", "/validate-ticket", true);
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("X-CSRF-TOKEN", csrfToken);
// Define the data to be sent in JSON format
var data = JSON.stringify({ barcode: barcode });
// Handle response from the server
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
console.log("Response from server:", xhr.responseText);
// Handle successful response if needed
} else {
console.error("Error:", xhr.status);
// Handle error response if needed
}
}
};
// Send the request with the data
console.log("CSRF Token:", csrfToken);
console.log("XHR object:", xhr);
xhr.send(data);
}
</script>
I send an ajax request to DashboardController where the validate ticket happen:
Route::controller(DashboardController::class)->group(function (): void {
// Route::get('/', 'index')->name('index');
Route::post('/validate-ticket', 'validateTicket')->name('validate');
});
DashboardController:
class DashboardController extends Controller
{
public function validateTicket(Request $request): RedirectResponse
{
$barcode = $request->input('barcode');
$ticket = Ticket::query()->where('code', $barcode)->first();
if ($ticket !== null) {
// Session::put('barcode', $barcode);
return redirect()->route('generate.ticket', ['barcode' => $barcode]);
}
return redirect()->route('generate.ticket');
}
}
And than it redirect me to Livewire Component:
`Route::get('/generate-ticket/{barcode}', TicketScannerComponent::class)->name('generate.ticket');
In LivewireComponent I have:
public null|string $barcode;
public string $orderId;
public string $ticketTypeId;
public BigInteger $usage;
public bool $isUsed;
public array|string $ticketData;
public function mount(?string $barcode = null): void
{
if ($barcode !== null) {
$ticket = Ticket::query()->where('code', $barcode)->first();
$this->barcode = $barcode;
// dd($this->barcode);
$this->orderId = $ticket['order_id'];
$this->ticketTypeId = $ticket['ticket_type_id'];
$this->isUsed = $ticket['is_used'];
}
}
And I can't access the $barcode variable
If you want to use that barcode in the same instance of Livewire component, you need to communicate with it using Livewire JavaScript API.
In the code you have pasted, when you scan a new barcode, your
sendBarcodeDatamethod makes an POST AJAX call to/validate-ticket, which validates your barcode and redirects that call to your Livewire component - creating second instance of your component. That redirection is than immediately discarded, as you don't do anything with the response fromxhr.send(data).Generally, when creating Livewire components, you should contain whole flow inside of the component (as it makes life easier). Instead of using AJAX calls, you should create another method on your component which you will call when the barcode is scanned. In following example, I have prepared
sendBarcodeDatamethod in livewire component (where you should put your validation and processing of a ticket):Which can be called as
$wire.sendBarcodeData([...])from the component Javascript.Please notice that the script is contained between
@scriptand@endscripttags, as it is required by documentation.