As I write here, I will show my errors using React with JavaScript. And I will put also my answers or the solution to that error, but doesnt mean is actually correct, because I am learning, but for me made sense, and also I look for youtube videos with seniors engineers using React, how they approach this error, and I think follows the principles that taught me in their videos. And thanks to @midudev, and great teacher.
Fetch errors so simple
The following code works, but doesnt catch the errors, and can break the system if it continues like this:
export const createUser = async (user_data) => {
const response = await fetch(CREATE_USER_EP,{
method: "POST",
body: JSON.stringify(user_data),
headers:{
"Content-Type": "application/json",
}
});
const data = await response.json();
let status = response.status;
return { status, data}
}
And the solution is control the errors I know can break the system:
export const createUser = async (user_data) => {
let result = {created:false, error: null, message: null, code: null};
try{
const response = await fetch(CREATE_USER_EP,{
method: "POST",
body: JSON.stringify(user_data),
headers:{
"Content-Type": "application/json",
}
});
if(!response.ok){
result = {created:false, error: `Ocurrio un error del sistema, codigo:
${response.status}, lo sentimos`, code: response.status}
return result;
}
const data = await response.json();
console.log("data: ", data);
return {created: true, error: null, message: data, status: response.status}
}catch(error){
throw new Error("Error de comunicacion con nuestros servicios, lo
sentimos.")
}
}
The same error but different fetch to the API:
export const getShops = async () => {
const response = await fetch(LIST_SHOPS);
const data = await response.json();
let ok = response.ok;
console.log(data);
return {ok, data};
}
And the solution: control the errors, I also have added console.logs to see if it's working, to test.
export const getShops = async () => {
let result = {success: false, error: '', data: {}}
try{
const response = await fetch(LIST_SHOPS);
if(!response.ok){
return {...result,
error: `codigo: ${response.status}, ocurrio un error en los servicios, lo sentimos`}
}
const data = await response.json();
console.log("getShops function, data: ", data);
return {...result, success: true, data: data}
}catch(error){
throw new Error("Error conectandose a nuestro servicios");
}
}
Redundant code that doesnt make sense
import { useState, useEffect } from 'react';
import { useMultiStepForm } from '../../context/FormProvider';
import InfoButton from '../../components/GetFormData';
import '../../static/css/house/upload_add.css';
const MAX_FILE_MB = 6;
const ONE_MB = 1000 * 1000;
const MAX_FILE_SIZE = MAX_FILE_MB * ONE_MB;
export default function UploadFile() {
const { formData, updateFormData, nextStage } = useMultiStepForm();
const [message, setMessage] = useState(["", ""]);
const [fileName, setFileName] = useState("");
const [selectedFile, setSelectedFile] = useState(null);
useEffect(() => {
if (formData?.post && formData.post?.file) {
setSelectedFile(formData.post.file);
}
}, [formData]);
function handleChange(e){
const file = e.target.files[0];
if(!file) return;
setMessage(['','']);
if(file.size > MAX_FILE_SIZE){
setMessage(['',`El tamaño del archivo supera los ${MAX_FILE_MB} MB`]);
e.target.value = '';
setSelectedFile(null);
updateFormData({post: {file: null}});
return;
}
setSelectedFile(file);
updateFormData({post: {file:file}})
const sizeMB = (file.size / ONE_MB).toFixed(2);
setMessage([`Archivo valido: ${sizeMB} MB`,'']);
}
function save_file(e) {
e.preventDefault();
if(!selectedFile){
setMessage(["No se ha seleccionado ningun archivo.", ""]);
}else{
nextStage();
}
}
return (
<div>
<form className='upload-add-form' onSubmit={save_file}>
<label htmlFor='file'>Elija un archivo pdf de su anuncio</label>
<input
type='file'
name='file'
accept='.pdf'
onChange={handleChange}
/>
{selectedFile && (
<div className='file-info'>
<p>Archivo seleccionado: {selectedFile.name}</p>
</div>
)}
{message[0] && <p className="message-error">{message[0]}</p>}
{message[1] && <p className="message-info" style={{ color: "red" }}>
{message[1]} MB</p>}
<button type="submit">Siguiente</button>
</form>
{/* <InfoButton /> */}
</div>
);
}
And the errors are:
- Doesn't have meaningful names in the error messages: ["error1","error2"].
- And I find that is some kind of unnecesary complexity using selectedFile and formData.
The first error, is that to upload the file, in the handleChange() method, I update to states:
setSelectedFile(null);
updateFormData({post: {file: null}});
-----
setSelectedFile(file);
updateFormData({post: {file:file}})
But if I think clearly, we just have one goal here: Users need to upload a file, and happens when the "Siguiente" button is clicked.
And to keep track those changes, I dont need to update the states, just one, and that is `selectedFile` and not the `updateFormData`.
One more thing, I have a `useEffect`:
useEffect(() => {
if (formData?.post && formData.post?.file) {
setSelectedFile(formData.post.file);
}
}, [formData]);
So formData relies on selectedFile to give the current file. And doesn't makes sense to be on the contrary.I just update formData when "Siguiente" button is clicked. And I update selectedFile only on the onChange event is triggered.
Another error is in an array, the first is for info message and other for errors message.
const [message, setMessage] = useState(["", ""]);
But it's implicit meaning, so I need to put explicit meaning:
const [message, setMessage] = useState({
info: '',
error_message: ''
});
And if the users decides to go back to this form, when it's in the next form, I will put by default the file previously stored.
const [selectedFile, setSelectedFile] = useState(formData?.post?.file);
And the final version with all these changes is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
|
I will edit this, maybe doesnt understand well, and if you have any doubt please contact me. I hope this is helpful to understand what I did to improve, and it's just tiny things that together can be more reliable your code also. I dont touch yet the tests(an error), but I will continue to improve this. 😁👍👍