400 Bad request MP4 (Express, Node, React,mongoDB ) - javascript

I am trying to stream a mp4 file that is on my computer. I am able to upload and delete the files. When the upload completes and click the link. it routes me to the page and I only see {}. and I get the following errors:
GET http://localhost:8000/read/c94e2bfe215bb8821c5c8dc22c8dc1b4.mp4 400 (Bad Request)
favicon.ico:1 GET http://localhost:8000/favicon.ico 404 (Not Found)
I even uploaded a picture to see to check if the mp4 file was too big, but the picture did not load as well.
Here is my code for my server:
// route for streaming a file
app.get('/read/:filename',async(req,res)=>{
const{filename}= req.params
try{
const readstream = await gfs.createReadStream({filename})
res.header("Content-Type","video/mp4");
res.header("X-Content-Type-Options", "nosniff");
res.header("Accept-Ranges", "bytes");
res.header("Content-Length",903746);
readstream.pipe(res)
}catch(err){
res.status(400).send(err)
}
})
Here is the code for react
function App() {
const [file, setFile] = React.useState(null);
const [files, setFiles] = React.useState([]);
const filehandler = (e) => {
if (e.target.files != null || e.target.files[0] != null) {
setFile(e.target.files[0]);
}
};
const uploadFile = async (e) => {
e.preventDefault();
if (file) {
const fd = new FormData();
fd.append("file", file);
const res = await axios.post("http://localhost:8000/upload", fd);
setFiles(files.concat(res.data))
}
};
const fetchFiles = React.useCallback(async () => {
const res = await axios.get("http://localhost:8000/files");
setFiles(res.data);
}, []);
const removeFile = React.useCallback(
async (filename, index) => {
const res = await axios.delete(
`http://localhost:8000/delete/${filename}`
);
if (res.status === 200) {
let temp = [...files];
console.log(temp);
temp.splice(index, 1);
setFiles(temp);
}
},
[files]
);
React.useEffect(() => {
fetchFiles();
}, [fetchFiles]);
return (
<div className="App">
<form className="Form" onSubmit={uploadFile}>
<input type="file" onChange={filehandler} />
<button type="submit">upload</button>
</form>
<div className="Media">
{files.map((file, i) => (
<div key={file._id} className="Item">
<a
className="Link"
href={`http://localhost:8000/read/${file.filename}`}
>
{file.filename}
</a>
<button
type="button"
onClick={() => {
removeFile(file.filename, i);
}}
>
remove
</button>
</div>
))}
</div>
</div>
);}

Your router is sending 400 after catching an exception. Print exception message using console.log(err) in your catch block to determine what exactly goes wrong it try block's code

Related

How to show progress bar while uploading multiple images to Firebase Storage?

I made function that upload multiple images to storage and save links to document but i can't figure out how to monitor progress.
const getURLS = async () => {
const promises = [];
images &&
images.map((image) => {
const storageRef = ref(storage, `images/${image?.file?.name + v4()}`);
promises.push(
uploadBytesResumable(storageRef, dataURLtoBlob(image.data_url)).then((uploadResult) => {
return getDownloadURL(uploadResult.ref);
})
);
});
const urls = await Promise.all(promises);
try {
await addDoc(collection(db, 'posts'), {
message: data,
createdAt: serverTimestamp(),
createdBy: user,
likes: [],
comments: [],
images: urls,
}).then(() => {
setData('');
setImages([]);
});
} catch (err) {
console.log(err);
}
};
How to add firebase monitor upload progress to this function?
I tried different ways but it dosn't work
thx for help
The uploadBytesResumable() does not return a promise but an UploadTask. You can iterate over all the images selected and track their progress individually as shown below:
function App() {
const [images, setImages] = useState([])
const [progress, setProgress] = useState([])
const handleFileChange = (e) => {
const files = e.target.files
const newImages = []
for (let i = 0; i < files.length; i++) {
newImages.push(files[i])
}
setImages(newImages)
}
const handleUpload = async () => {
for (let i = 0; i < images.length; i++) {
const image = images[i]
const storageRef = ref(storage, `images/${image.name}`)
const uploadTask = uploadBytesResumable(storageRef, image)
uploadTask.on('state_changed', (snapshot) => {
const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100
setProgress((prevProgress) => {
const newProgress = [...prevProgress]
newProgress[i] = progress.toFixed(2)
return newProgress
})
}, (error) => {
console.log(error)
}, async () => {
const imageUrl = await getDownloadURL(uploadTask.snapshot.ref)
// Add to Firestore
})
}
}
return (
<div className="App">
<input type="file" multiple onChange={handleFileChange} />
<button onClick={handleUpload}>Upload</button>
{progress.map((progress, i) => (
<div key={i}>{images[i].name} {progress}%</div>
))}
</div>
)
}
Each file is uploaded separately so you would have to implement some logic to get all URLs together and add in Firestore document like you can call a function when progress of all uploads i.e. all items in progress array become 100.

How do I display a blob octet stream in React? Pinged server, made blob url but doesn't display in SRC of image?

I am trying to display an image on a profile of a user. I have been able to fetch the blob from the API and convert it to a URL blob but when I am trying to return it from the function and into the SRC of the tag, nothing is being displayed.
Previously I was simply displaying the image with <src = ""> and the src that I have put in the function, but when I implemented authentication, this no longer worked because there was a 401 unauthenticated error since no bearer token was sent with the request.
Output:
//profile.js
export const Profile = () => {
const [userProfileInformation, setUserProfileInformation] = useState([]);
const [isLoading, setLoading] = useState(true);
const { userId } = useParams();
useEffect(() => {
getUserProfileInformation().then(() => {
setLoading(false);
});
}, []);
const getUserProfileInformation = async () => {
const response = await UserService.getUserProfileInformation(userId)
.then(response => response.json())
.then(data => {
setUserProfileInformation(data);
});
}
const getProfileImage = async () => {
const src = config.URL + "/users/" + userProfileInformation.userId + "/image/download";
const options = {
headers: {
"Authorization" : `Bearer
${AuthService.getCurrentlyAuthenticatedUser().accessToken}`,
}
};
fetch(src, options)
.then(res => res.blob())
.then(blob => {
console.log(blob);
let url = URL.createObjectURL(blob);
console.log(url);
return url;
});
}
if (isLoading) {
return (
<div id="loading">
<h2>Loading...</h2>
</div>
)
}
return (
<div>
<AppNavbar />
<div className="profileCard">
<img id="profileImg" src={getProfileImage()}/>
<h1>{getFullName(userProfileInformation.firstName, userProfileInformation.lastName)}</h1>
<h2 id="email" role="email">{userProfileInformation.email}</h2>
<h2>{userProfileInformation.location}</h2>
)
}
Any help would be appreciated, thanks.

Can' t delete image from Firebase Storage REACT 2022

I have this code from firebase documentation on my firebase file
export async function deleteImage(docId){
// Create a reference to the file to delete
const desertRef = ref(storage, `images/${docId}`);
await deleteObject(desertRef).then(() => {
swal("GOOD", "success");
}).catch((error) => {
swal("error!", "error");});
}
➡️ And i have this code for upload and download URL image on my Dashboard View
async function handleOnChangeProfileImage(e) {
console.log(e.target);
setLoading(true) // Setloading to true
var fileList = e.target.files;
var fileReader = new FileReader();
if (fileReader && fileList && fileList.length > 0) {
fileReader.readAsArrayBuffer(fileList[0]);
fileReader.onload = async function () {
var imageData = fileReader.result;
const res = await setUserProfilePhoto(currentUser.uid, imageData);
if (res) {
const tmpUser = { ...currentUser };
tmpUser.profilePicture = res.metadata.fullPath;
setCurrentUser({ ...tmpUser });
await updateUser(tmpUser);
const url = await getProfilePhotoUrl(currentUser.profilePicture);
setProfileUrl(url);
//updateUserProfilePhoto(currentUser.uid, res.fullPath);
}
};
}
}
➡️ And this is in html
<img className="mb-3 lazyload" key={profileUrl} srcSet={profileUrl} data-src={userImg}
width={200} alt="web.app" />
<Button onClick={handleOpenFilePicker} variant="primary"><FontAwesomeIcon icon={faUpload} /> Upload</Button>
<Button onClick={deleteImage} variant="danger"><FontAwesomeIcon icon={faDeleteLeft}/> Delete</Button>
I can upload an image successfully, but i want to delete the user's profile image with a OnClick event, and for that I use his docId as a reference, but the result is negative, what else do I have to create or do to delete the uploaded image? Hope you help me!! Thanks a lot!

Javascript react safe image in database

I have a problem with saving pictures in the database. I want to do a post Method, where i can safe a file in a directory and save the picture link in the database.
Here is my Code:
`const toBase64 = file => new Promise((resolve, reject) => {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => resolve(reader.result)
reader.onerror = error => reject(error)
})`
` const [base64Image, setBase64Image] = useState("")
const [imagePath, setImagePath] = useState("")
const fileInput = useRef(null)`
`const onFileInputChange = async (e) => {
const file = fileInput.current.files[0]
if (!file) return
const base64 = await toBase64(file)
setBase64Image(base64)}`
` const handleSubmitImage = async (e) => {
e.preventDefault()
if (!base64Image) return
const response = await fetch("/public", {
method: "POST",
headers: {
"content-type": "application/json"
},
body: JSON.stringify(base64Image)
})
const data = await response.json()
setImagePath(data.filePath)
}`
Post:
`const handleSubmit = async (e) => {
e.preventDefault()
setIsLoading(true)
setErrors(defaultModel)
const result = validateModel(post)
if (!result.isValid) {
setErrors(result.errors)
setIsLoading(false)
return
}
if (post.id) {
await updatePost(post, session.accessToken)
alert("Post updated!")
router.push(`/posts/${post.id}`)
} else {
const newPost = await createPost(post, session.accessToken)
alert("Post created!")
router.push(`/posts/${newPost.id}`)
}
setIsLoading(false)
}
`
` <fieldset onSubmit={handleSubmitImage} className={styles.form}>
<p>Image:</p>
<input value={post.image}
type="file"
accept=".png,.jpg"
ref={fileInput}
onChange={onFileInputChange}
/>
{/* eslint-disable-next-line #next/next/no-img-element */}
{base64Image && <img src={base64Image} style={{width: "1000px", height: "1000px"}} alt={""}/>}
{imagePath && <p>
<Link href={`http://localhost:3000${imagePath}`}
passHref><a>http://localhost:3000{imagePath}</a></Link>
</p>
}
</fieldset>`
Right now i can connect to the Explorer and pick an Image. I can also display the image. If i press on create, it doesnt work properly with saving the image in the database.

React-dropzone new reader onload slowly working

When I request api, I want to make conditional according to the answer, but it doesn't assign the value I want to errorMessageUploaded. Do you have an idea?
I want to get a message when the error comes from api, but when the response comes errormessageupload variable without ending the request.
Not working conditional.
let uploadLoading = false;
let errorMessageUploaded = null;
`function Previews(props) {
const [files, setFiles] = useState([]);
const [test, testFile] = useState(null);
const { getRootProps, getInputProps } = useDropzone({
noClick: props.uploadDisable,
accept: "application/vnd.ms-excel,
application/vnd.openxmlformats-
officedocument.spreadsheetml.sheet",
onDrop: acceptedFiles => {
uploadLoading = true;
var file = acceptedFiles[0];
fileName = file.path;
const reader = new FileReader();
let data = {
file: null,
purchase_order_id: props.purchaseorderid
};
reader.onload = event => {
uploadLoading = true;
data.file = event.target.result.replace(
"data:application/vnd.openxmlformats-
officedocument.spreadsheetml.sheet;base64,",
""
);
});
(async () =>
await axios
.post(
baseUrl + "v1/purchaseorder/uploadpurchaseorder",
data,
axiosConfig
)
.then(response => {
uploadLoading = false;
errorMessageUploaded = null;
window.location.reload();
})
.catch(error => {
errorMessageUploaded = "test";
uploadLoading = false;
throw error;
}))();
reader.readAsDataURL(file);
}
});
const thumbs = files.map(file => (
<FontAwesomeIcon icon={faFileExcel}
className="excelUploadThumbs" />
));
useEffect(
() => () => {
// Make sure to revoke the data uris to avoid memory leaks
files.forEach(file => URL.revokeObjectURL(file.preview));
},
[files]
);
return uploadLoading == false ? (
<section className="container">
<div {...getRootProps({ className: "dropzone" })}>
<input {...getInputProps()} />
<p className="dropzoneText1">Drop your file here</p>
<p className="dropzoneText2">or</p>
<p className="dropzoneText3">Select file</p>
</div>
<aside style={thumbsContainer}>{thumbs}</aside>
</section>
) : errorMessageUploaded != null ? (
<section className="container">
<div className="displayErrorDiv">
<p className="serviceError"> {errorMessageUploaded} </p>
</div>
</section>
) : (
<section className="container">
Data is uploading...
<aside style={thumbsContainer}>{thumbs}</aside>
</section>
);
}`
Code unclear but these may be helpful.
use uploadLoading & errorMessageUploaded with useState
need cancelToken
let source = Axios.CancelToken.source();
const Send = async (url, method, data) => {
try {
source && source.cancel("Operation canceled due to new request.");
source = Axios.CancelToken.source();
return await Axios({ method, url, data, cancelToken: source.token });
} catch (error) {
if (Axios.isCancel(error)) {
return Promise.resolve("canceled");
} else {
return Promise.reject(error);
}
}
};

Categories

Resources