extract text from image and show it in html page - node.js

i have a problem : i made a function to extract text from image with ocr space api in backend when i called it with postTypeRequest(...) in angular it worked
i added a declaration text: string and i gave it the extracted text from backend to call it in html tag and show results in my project but it shows this problem : Type 'Object' is not assignable to type 'string'
the console shows an empty data like this :
[1]: https://i.stack.imgur.com/PmRDn.png
ress is empty and its type is object
so i think ress should return string not object
home.component.ts
onSubmit() {
console.log('image', this.image);
const formData = new FormData();
formData.append('file', this.image ,'file');
return this.api.postTypeRequest('/api/scan/images', formData).subscribe((res) => {
console.log(res) ;
this.text =res //add a variable to call it in html {{text}} and show results
} )
}
scan.controller.js
const uploadImage = (req,res)=> {
let imageDetails = {
name: req.file.originalname,
};
Scan.find({ name: imageDetails.name }, (err, callback) => {
if (err) {
res.json({
err: err,
message: `There was a problem creating the image because: ${err.message}`,
});
} else {
let attempt = {
name: req.file.originalname,
imageUrl: req.file.path,
imageId: "",
};
cloudinary.uploads(attempt.imageUrl).then((result) => {
let imageDetails = {
name: req.file.originalname,
imageUrl: result.url,
imageId: result.id,
};
Scan
.create(imageDetails)
.then((image) => {
imageFilePath =imageDetails.imageUrl
const rlt = ScanService.createScan(imageFilePath).then( ()=>{
res.json({
success: true,
data: image,
ress : rlt
});
})
})
.catch((error) => {
res.json({
success: false,
message: `Error creating image in the database: ${error.message}`,
});
});
});
}
});
}
scan.service.js
const createScan = async (imageFilePath) => {
ocrSpaceApi.parseImageFromUrl(imageFilePath, options)
.then(function (parsedResult) {
console.log('parsedText: \n', parsedResult.parsedText);
console.log('ocrParsedResult: \n', parsedResult.ocrParsedResult);
return parsedResult.parsedText,parsedResult.ocrParsedResult
}).catch(function (err) {
console.log('ERROR:', err);
})}```

The error is ocorring because you have an Object on the JSON response, so you need to check before assign the String value to your text.
In this case i yould recomendo you using a type check to make sure you are receiving your data as you expect.
Something on the lines of
if(typeof res !== "string") {
this.text = "";
return;
}
this.text = res;

Related

FInding difficulty in updating a doc in MERN stack React Native

I don't know where II am missing something in the code as It's working clearly from postman.
my backend Nodejs server function is :
exports.updateFCMToken = (req, res) => {
try {
User.findByIdAndUpdate(
req.params.id,
{
$set: {
fcmToken: req.body.fcmToken
}
},
(err, doc) => {
if (err) {
console.log(err);
res.status(400).send('update FCMToken - Error')
}
return res.status(200).send('FCMToken Updated Successfully')
}
)
}
catch (err) {
console.log(err);
res.status(400).send('server Error - FCMToken')
}
}
From component I am calling the action:
useEffect(() => {
setTimeout(async () => {
dispatch(updateFCMTokenAction());
}, 1000);
}, [])
my action.js: (doc id and fcmtoken are not similar to output shown in code)
export const updateFCMTokenAction = () => {
return async (dispatch) => {
try {
dispatch({ type: userConstants.UPDATE_FCMTOKEN_REQUEST });
getToken();
const fcmToken = await AsyncStorage.getItem('fcmToken');
const user = await AsyncStorage.getItem('user');
const pushToken = {fcmToken};
const id = JSON.parse(user)._id; // output: 63806e0f4dzeb09a2c03f731
console.log('-----------------updateFCMTokenAction--------------');
console.log('updateFCMTokenAction-fcmToken:', pushToken); // output: {"fcmToken": "fv4-4GIWTymgrt7e3klaPs:APA91bGXOLTNfp4-j4dPVDEL-6lDVUA7GWZchwx4j2BlVPOvOsq3pDOk06xkfBE-Q-J6Q4zix8LX-Jf-69Ey2T22aYmbiVD4j4_kMbVlZa8ip1MRtQ-ZDs0hMpno53o7BjmB9Opc-LWR"}
const res = await axiosInstance.post(`/updatefcmtoken/${id}`, pushToken);
console.log('res: ', res);
dispatch({ type: userConstants.UPDATE_FCMTOKEN_SUCCESS, payload: res.data });
} catch (err) {
console.log('push-err: ', err)
dispatch({ type: userConstants.UPDATE_FCMTOKEN_FAILURE, payload: err });
}
}
}
I am getting an error as :
push-err: [AxiosError: Request failed with status code 400]
What am I missing/unable to see here ?
Thank You ,

problem in sending base64 data in GET request

Hi I am facing issues sending base64 data in GET request.
I was successful in converting the image into base64 data and inserting it in receivedFile
but during response the attachments come as an empty array while the rest of the data i.e user_id is flowing successfully.
Hence if you could please help me to resolve this issue.
Below is the code
router.js
router.get('/users/data/expand/:nid',async (req,res) => {
var idselected = req.params.nid;
var dir = '\images';
var receivedFile = [];
try {
const checkData = await user.find({"user_id": idselected});
await checkData[0].attachments.forEach (element => {
fs.readdir(dir,function(err,files) {
if(err) {
console.log(err)
}else {
files.forEach((filename) => {
filename = element;
fs.readFile(filename,'base64', (err,base64Data) => {
if(err) {
console.log(err);
}
receivedFile.push(base64Data);
})
})
}
})
})
//issue is here the attachments is coming as empty instead of base64 data
const returnUser = new User({
user_id: checkData.user_id,
attachments: receivedFile
})
res.status(201).send(returnUser);
}
catch(e) {
res.status(500).send(e)
}
})
Well its always good to create helper functions and to promisfy it so you can use async / await syntax.
I have changed your code. I didnt tested it but i guess it should work:#
router.get("/users/data/expand/:nid", async (req, res) => {
var idselected = req.params.nid;
var dir = "images";
try {
const checkData = await user.findOne({ user_id: idselected });
let receivedFile = await Promise.all(
checkData.attachments.flatMap(async element => {
let files = await readDirectory(dir);
return await Promise.all(
files.map(filename => {
filename = element;
return readFile(filename)
})
);
})
);
const returnUser = new User({
user_id: checkData.user_id,
attachments: receivedFile
});
let savedUser = await returnUser.save();
res.status(201).send(savedUser);
} catch (e) {
res.status(500).send(e);
}
});
function readDirectory(dir) {
return new Promise((res, rej) => {
fs.readdir(dir, function(err, files) {
if (err) {
rej(err);
} else {
res(files);
}
});
});
}
function readFile(filename) {
return new Promise((res, rej) => {
fs.readFile(filename, "base64", (err, base64Data) => {
if (err) {
rej(err);
}
res(base64Data);
});
});
}
I guess you use mongoose.
There is an method called findOne and also you forgot to save your model with returnUser.save()

How to add item with image with react-redux-saga with nodejs/multer

I am trying to save an item that has images in the form. I was able to save the items using postman, but getting issue when trying from react-redux-saga. I am using ant design for the form.
Front-end code:
handleSubmit = e => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
const { fileList } = this.state;
const formData = new FormData();
fileList.forEach(file => {
formData.append("files[]", file);
});
const postItemData = { ...values, images: formData };
this.props.createItem(postItemData);
}
});
};
saga:
When I try to console, I can get the item details with the image field as a formdata
{
let itemData = yield select(makeSelectPostItemData());
const token = yield select(makeSelectToken());
console.log(itemData, "itemData");
const response = yield call(request, `/item`, {
method: "POST",
headers: {
Authorization: `${token}`
},
body: JSON.stringify(itemData)
});
const successMessage = "Item saved successfully!";
yield put(postItemSuccess(response, successMessage));
}
nodejs:
const upload = multer({
storage: storage,
limits: { fileSize: 1000000 },
fileFilter: function(req, file, cb) {
checkFileType(file, cb);
}
}).array("images");
upload(req, res, err => {
if (err) {
console.log(err, "error");
res.send({ msg: err });
} else {
console.log(req, "req");
if (req.files === undefined) {
res.send({ msg: "Error: No file selected!" });
} else {
const { errors, isValid } = validatePostItem(req.body);
// check validation
if (!isValid) {
return res.status(400).json(errors);
}
const files = req.files;
}
}
});
On the last line const files = req.files. When I try from postman, I get file details, but when I try to request it from react, I have no req.files. How can I get the req.files from the react as I am getting from postman?
I have found the solution for this. In the handleSubmit, I have following code:
fileList.forEach(file => {
formData.append("files[]", file);
});
const postItemData = { ...values, images: formData };
this.props.createItem(postItemData);
Instead of spreading values and inserting the formData in images, what I did was put the all of them into formData.
fileList.forEach(file => {
formData.append("files[]", images);
});
formData.append("name", values.name);
formData.append("price", values.price);
formData.append("detail", values.detail);
this.props.createItem(formData);
With this, I could get req.files and req.body.name, req.body.price, req.body.detail in the node side. Quite different from the postman, but this worked for me.

Axios POSTed FormData has empty body on serverside

This is the client side code. Data is not empty, file is getting uploaded correctly.
export function addGame(data) {
return dispatch => {
const formData = new FormData();
formData.append("game.cover", data.gameCover[0]);
formData.append("game.title", data.gameTitle);
formData.append("game.price", data.gamePrice);
formData.append("game.description", data.description);
return axios.post(apiUrl + "/games/add", formData).then(res => {
dispatch({ type: ADD_GAME, payload: res.data.game });
});
};
}
and this is the serverside
router.post("/add", auth, async (req, res) => {
const body = await req.body;
console.log(body);
let formErrors = [];
if (!body.gameTitle) formErrors.push("Game title is required.");
if (!body.description) formErrors.push("Description is required.");
if (!body.gamePrice) formErrors.push("Price is required.");
if (formErrors.length) res.status(400).send({ success: false, formErrors });
else {
let gameCoverFileName;
if (!fileUpload(req, gameCoverFileName))
formErrors.push("Failed to upload file");
const result = await gameModel.create({
title: body.gameTitle,
cover: gameCoverFileName,
price: body.gamePrice,
description: body.description
});
if (result)
res.status(201).send({
success: true,
game: {
gameTitle: result.title,
gameCover: gameCoverFileName,
gamePrice: result.price,
description: result.description
}
});
} });
And I'm getting empty body
You need to additionally process the multipart form-data. For example with multiparty:
const multiparty = require("multiparty");
router.post("/add", auth, async (req, res) => {
try {
const parse = function (req) {
return new Promise(function(resolve, reject) {
const form = new multiparty.Form()
form.parse(req, function(err, fields, files) {
!err ? resolve([fields, files]) : reject(err)
})
})
}
const [body] = await parse(req)
console.log(body)
} catch (err) {
console.log(err)
}
res.json("ok")
})

MEAN Stack Cannot Update MongoDB Record using PUT method

Cannot update mongoDB record, using PUT method. Parameters are passing correctly, there must be a problem within a query I guess.
Schema
let Boards = new mongoose.Schema({
title: String,
description: String,
lastUploaded: Number,
owner_id: String
});
Server:
module.exports.updateTime = function (req, res) {
let board = new Board();
let id = new mongoose.Types.ObjectId(req.body._id);
let myquery = { _id: id };
let newvalues = { lastUploaded: req.body.time };
console.log("New time: " + req.body.time); //Number recieved
console.log("Id: " + req.body._id); //String recieved
board.findByIdAndUpdate(myquery, newvalues, function (err, response) {
if (err) {
response = { success: false, message: "Error updating data" };
} else {
response = { success: true, message: "Data updated" };
}
res.json(response);
});
board.close();
};
Client:
public updateTime(updateOptions: UpdateTime): Observable<any> {
let headers = new Headers;
let URI = `${apiUrl}/updateTime`;
headers.append('Content-Type', 'application/json');
return this.http.put(URI, updateOptions, { headers: headers })
.map(this.extractData)
.catch(this.handleError);
}
Router:
router.put('/updateTime', ctrlContent.updateTime);
Finally gave me empty response error through .catch(this.handleError);
There are two bugs that I can see.
First, the first argument to the findByIdAndUpdate method should be an _id itself, not an object with an _id property:
// this will not work
board.findByIdAndUpdate({ _id: id }, newvalues, handler);
// this is how it should be
board.findByIdAndUpdate(_id, newvalues, handler);
Second, you are calling board.close(); outside of the query callback. Closing a connection is propably a mistake, but even if you absolutely need it, you should do it inside the callback function.
Here is a complete server example:
module.exports.updateTime = function (req, res) {
let id = req.body._id;
let newvalues = { lastUploaded: req.body.time };
Board.findByIdAndUpdate(id, newvalues, function (err, response) {
if (err) {
res.json({ success: false, message: "Error updating data" });
} else {
res.json({ success: true, message: "Data updated" });
}
});
};

Resources