It returns a pdf with the API request and I save this pdf to the src/pdfs location with the name 'label.pdf' and when I open this pdf file, it opens it with a hash code. I have no idea how to prevent this.
My Component:
const getLabels = useSelector(state => state.getLabel)
const {time,loading:loadingLabel,success:successLabel} = getLabels
useEffect(() => {
if(successLabel === true && loadingLabel === false){
window.open(require('../pdfs/label'+time+'.pdf') ,"_blank")
dispatch({type:LABEL_GET_RESET})
}
},[dispatch,navigate,successLabel,time,loadingLabel])
Related
I have a code that lets me upload images to react-easy-crop package. I also have an "x" button that removes the image so the user can reupload another image. The problem I'm facing now is that when the user removes an uploaded image, they are unable to re-upload the same image.
The code for the upload component:
const onSelectFile = (event: any) => {
if (event.target.files && event.target.files.length > 0) {
if (!allowedFileTypes.some(x => x === event.target.files[0].type || event.target.files[0].size > 10000000) {
setImage('')
setError('Failed to upload. Inccorect size or file type');
}
else {
setError('')
reader.readDataAsDataURL(event.target.files[0]);
reader.addEventListener("load", () => {
setImage(reader.result as string);
});
}
and for the remove button, i did this:
const onRemoveImg = () => {
setImage('')
}
With these few info I have to guess...
Try to use .createObjectURL instead of fileReader, it is synchronous, but it ight help you to debug if that particular issue depends from fileReader being stuck if you try to read the same file twice...
const onSelectFile = (event: any) => {
if (event.target.files && event.target.files.length > 0) {
if (!allowedFileTypes.some(x => x === event.target.files[0].type || event.target.files[0].size > 10000000) {
setImage('')
setError('Failed to upload. Inccorect size or file type');
}
else {
setError('')
const img : string = window.createObjectURL(e.target.files[0])
setImage(img);
});
}
I am want to save image as base64 to aws s3 bucket. There is a lambda that will decoder the base64.
These are my current states for the images. One is for selected file that is the image and the one is for the image that is seen as preview on the page.
const [selectedFile, setSelectedFile] = useState('')
const [preview, setPreview] = useState()
Then I have useEffect function for selecting the file and also sets the object URL as the preview image.
useEffect(() => {
if (!selectedFile) {
setPreview(undefined)
return
}
const objectURL = window.URL.createObjectURL(selectedFile)
setPreview(objectURL)
return () => window.URL.revokeObjectURL(objectURL)
}, [selectedFile])
const selectFile = (event) => {
setSelectedFile(event.target.files[0])
}
And this is the input component where the onChange function is called.
<Input
style={input}
type='file'
accept='.jpg, .png|image/*'
id='image'
name='Upload image'
onChange={selectFile}
/>
Is there a better way to handle the base64 conversion?
I managed to solve this by relatively short lines of code. I take the selectedFile from the state and then convert it to base64. I tested it with the separate button and I got base64 image in the console.
const convertToBase64 = () => {
const reader = new FileReader()
reader.readAsDataURL(selectedFile)
reader.onload = () => {
console.log('called: ', reader)
setBase64IMG(reader.result)
}
}
I'm using the library JSZip to read a user-uploaded zip file and I want to load the contents of each file into the state.
Here's a toned-down version of reading the zip file:
const [files, setFiles] = useState([]);
const onUploadClick = () => {
const load = (filename) => {
return new Promise(
(resolve) => {
jzip.file(filename).async(`arraybuffer`).then(
(content) => {
return resolve(Array.from(new Uint8Array(content)));
}
)
}
)
}
jzip.loadAsync(file).then(
(zip) => {
zip.forEach(
async (_, entry) => {
const filename = entry[`name`];
const buffer = await load(filename);
const newFiles = [...files];
newFiles.push(buffer);
setFiles([...newFiles]);
)
}
)
}
I then used useEffect to monitor the changes to the files state component:
useEffect(
() => {
console.log(files)
},
[files]
);
But what I get out is just the following when trying to load a zip file with 3 files inside:
Instead, I am expecting something like
[Array(33), Array(33), Array(33)]
So it's reading each file correctly, converting to a Uint8Array, and adding it to the state, but the state is not retaining the previous files.
I also tried pushing just the filename into the files state component, and same error.
I am unsure why this is happening. Any advice is appreciated. Thank you!
Fixed code below:
const [files, setFiles] = useState([]);
const onUploadClick = () => {
const load = (filename) => {
return new Promise(
(resolve) => {
jzip.file(filename).async(`arraybuffer`).then(
(content) => {
return resolve(Array.from(new Uint8Array(content)));
}
)
}
)
}
jzip.loadAsync(file).then(
(zip) => {
const newFiles = [];
zip.forEach(
async (_, entry) => {
const filename = entry[`name`];
const buffer = await load(filename);
newFiles.push(buffer);
}
)
setFiles(newFiles);
)
}
The state update setFiles was not finished yet before trying to add a new entry, therefore files was not updated yet when trying to add a 2nd one. Same for the third file: it pulled the current files array (which was still empty, because the state update before it had not finished) and pushed something new. That's why there was only ever one item in the list.
I have this small issue
I am using Ant Design and its components
https://ant.design/components/upload/
I am trying to upload images, and it all works fine, But i need to add a validation to verify if the file is correct. That is if a user renames any other file to a .jpg or .png extension, i need to validate that and show them an alert.
How can i achieve that, Currently we convert the image in base64 using FileReader
You can create a function and return something like this.
const verifyImage = (img) => {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.addEventListener('load', event => {
let picFile = event.target
let imgNew = new Image()
imgNew.addEventListener('load', () => {
resolve(reader.result)
})
imgNew.addEventListener('error', () => {
reject()
})
imgNew.src = picFile.result
})
reader.readAsDataURL(img)
})
}
Working on a practice phonebook project where the visitor can enter a name and phone number. Utilizing json-server for the backend and React for front end.
The full code is here Phonebook Github Code
The functionality of adding a number works fine, but I'm having issues with a button which allows the visitor to delete a number. When a user clicks on the 'delete' button, it is successfully removed from the backend (file is db.json). However on the frontend, the deleted number isn't removed, and I can see that the state isn't changing.
Any help is appreciated.
Here's my delete function for removing the number from backend
const deletePerson = id => {
const request = axios.delete(baseUrl + `/` + id);
return request.then(response => response.data);
};
and this function is being called from a button onClick method
const deleteNum = event => {
let personID = event.target.value;
if (window.confirm("Do you really want to delete?")) {
personService
.deletePerson(personID)
.then(() => {
setPersons(persons.filter(item => item.id !== personID));
})
.catch(error => {
console.log("Error", error);
});
}
};
and the rest of the relevant code to give this context
const App = () => {
const [persons, setPersons] = useState([]);
const [newName, setNewName] = useState("");
const [newNumber, setNewNumber] = useState("");
const [filter, setFiltered] = useState("");
useEffect(() => {
personService.getAll().then(initialPersons => setPersons(initialPersons));
}, []);
console.log("Persons", persons);
const peopleToShow =
filter === ""
? persons
: persons.filter(person =>
person.name.toLowerCase().includes(filter.toLowerCase())
);
const rows = () =>
peopleToShow.map(p => (
<p key={p.name}>
{p.name} {p.number}{" "}
<span>
<button value={p.id} onClick={deleteNum}>
delete
</button>
</span>
</p>
));
item.id is stored as a number, whereas the personID is taken as a string. Hence, try changing !== to !=.