php - Javascript function await is only valid in async functions
?�have this app that uses OCR to read image text and convert it to JSON array then write it to an HTML table and export it as an Excel Worksheet by using phpspreedsheet the app was working so far so good until I played around it and missed up something after that Javascript function is not working anymore so it should work to write the table content to an Excel file by?�[Change.php]
prepare.js
function readFile(fileName) {
console.log({ fileName });
return await Tesseract.recognize(fileName, 'ara', {
logger: m => console.log(m)
});
}
function parseDataFromTextAndPropertyNames(text, propertyNames) {
console.log({ text, propertyNames });
return propertyNames
.reduce((table, key) =>
Object.assign(table, {
[ key ]: RegExp(`${ key }\\W+(\\w+)`)
.exec(text)?.[1] ?? ''
}), {});
}
function writeParsedTextDataAsJSON(fileName, table) {
console.log({ table });
JSON.stringify({ table });
// fake it ...
return (await new Promise(resolve =>
setTimeout(() => {
console.log({ fileName, json: JSON.stringify({ table }) });
resolve({ success: true });
}, 1500)
));
}
console.log('... running ...');
function start(filenames) {
const { data: { text } } = await readFile(filenames);
const data = await
parseDataFromTextAndPropertyNames(text, ['?�?�?�?� ?�?�?�???�?�', '?�?�?� ?�?�?????�??']);
document.getElementById("dvjson").innerHTML = JSON.stringify(data, undefined, 4);
const final = [JSON.stringify(data)];
const ff = [JSON.parse(final)];
constructTable('#table',ff);
htmlstring = getElementById('table').innerHTML();
$.post('change.php', {string:htmlstring}).done(function(response){
alert("done");
});
console.log({ result });
}
// construct JSON array to HTML Table
function constructTable(selector,data) {
// Getting the all column names
var cols = Headers(data, selector);
// Traversing the JSON data
for (var i = 0; i < data.length; i++) {
var row = $('<tr/>');
for (var colIndex = 0; colIndex < cols.length; colIndex++)
{
var val = data[i][cols[colIndex]];
// If there is any key, which is matching
// with the column name
if (val == null) val = "";
row.append($('<td/>').html(val));
}
// Adding each row to the table
$(selector).append(row);
}
}
function Headers(data, selector) {
var columns = [];
var header = $('<tr/>');
for (var i = 0; i < data.length; i++) {
var row = data[i];
for (var k in row) {
if ($.inArray(k, columns) == -1) {
columns.push(k);
// Creating the header
header.append($('<th/>').html(k));
}
}
}
// Appending the header to the table
$(selector).append(header);
return columns;
}
setTimeout(function() {
document.getElementById("loadspinne").style.display ="none";
document.getElementById("message").style.display = "block";
}, 8000);
prepare.php
<script src='scripts\prepare.js'></script>
<?php
if (!empty($target_file)){
echo '<script>start("'.$target_file.'")</script>';
}
?>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.16.2/xlsx.full.min.js"></script>
<script src='https://unpkg.com/tesseract.js@v2.1.0/dist/tesseract.min.js'></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
<link rel="stylesheet" href="style\main.css">
<script src="https://kit.fontawesome.com/bd514e8cb4.js" crossorigin="anonymous"></script>
<script src='excelexportjs.js'></script>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script>
<center>
<div id="loadspinne" style="width: 12rem; height: 12rem; color:#0A9ACD;" class="spinner-border" role="status"></div>
</div>
<div class="animate__animated animate__backInDown mx-auto d-block" style="display:none !important;" id="message">
<h4 style="font-family:Hana; font-size:32px; font-weight:bold;">???� ?????�???� ?????? ???�?�?�?�</h4>
</div>
</center>
<div class="container mt-5 ">
<div style="display:none;" id="dvjson"></div>
<table align="center" id="table" border="1" style="display:none;"></table>
</div>
</body>
</html>
Change.php
<?php
require 'vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Reader\IReader;
$htmlString = $_GET['htmlstring'];
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Html();
$spreadsheet = $reader->loadFromString($htmlString);
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xls');
$writer->save('ddd.xls');
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load("ddd.xls");
$sheet = $spreadsheet->getActiveSheet();
$sheet->getColumnDimension('A')->setAutoSize(false);
$sheet->getColumnDimension('B')->setAutoSize(false);
$sheet->getColumnDimension('A')->setWidth(16);
$sheet->getColumnDimension('B')->setWidth(13);
$sheet->getStyle('A1:B1')->getFont()
->setName('Arial')
->setSize(14)
->setBold(true);
$writer = new Xlsx($spreadsheet);
$writer->save('ddd.xlsx');
// header('Location: ddd.xlsx');
?>
Cosnole Log [Errors]:-
Uncaught SyntaxError: await is only valid in async functions and the top level bodies of modules (at prepare.js:4:10)
upload.php:4 Uncaught ReferenceError: start is not defined
at upload.php:4:9
(anonymous) @ upload.php:4
Answer
Solution:
Your issue is you are missing the async
keyword in some functions, because whenever you use await
it is mandatory to be used the async keyword
An async function is a function declared with the async keyword, and the await keyword is permitted within it. The async and await keywords enable asynchronous, promise-based behavior to be written in a cleaner style, avoiding the need to explicitly configure promise chains.
async function readFile(fileName) {
console.log({ fileName });
return await Tesseract.recognize(fileName, 'ara', {
logger: m => console.log(m)
});
}
async function parseDataFromTextAndPropertyNames(text, propertyNames) {
console.log({ text, propertyNames });
return propertyNames
.reduce((table, key) =>
Object.assign(table, {
[ key ]: RegExp(`${ key }\\W+(\\w+)`)
.exec(text)?.[1] ?? ''
}), {});
}
async function start(filenames) {
const { data: { text } } = await readFile(filenames);
const data = await
parseDataFromTextAndPropertyNames(text, ['?�?�?�?� ?�?�?�???�?�', '?�?�?� ?�?�?????�??']);
document.getElementById("dvjson").innerHTML = JSON.stringify(data, undefined, 4);
const final = [JSON.stringify(data)];
const ff = [JSON.parse(final)];
constructTable('#table',ff);
htmlstring = getElementById('table').innerHTML();
$.post('change.php', {string:htmlstring}).done(function(response){
alert("done");
});
console.log({ result });
}
Source