I'm posting an image to imgur, via their API. This is a ReactJS app on TS.
Here base64 is base64 string of the image, usually between 50 to 100kb
const imgurApi = axios.create({
headers: {
'Authorization': 'Client-ID xxx'
}
})
export async function postImgurImage(base64: string, username: string, desc: string) {
try {
const data = {
"image": base64,
"title": username,
"description": desc
}
const res = await imgurApi.post('https://api.imgur.com/3/image', data)
if (res.status === 200) {
console.log(res.data);
return res.data
} else {
return `Error: ${res.statusText}`
}
} catch (err) {
console.log(err);
return err
}
}
This works on postman, but when I try this on the browser, I get this error
Error: Request failed with status code 429
at createError (createError.js:16)
at settle (settle.js:17)
at XMLHttpRequest.handleLoad (xhr.js:62)
EDIT 1
This is how the postImgurImage is being called.
const handleImg = (e: React.ChangeEvent < HTMLInputElement > ) => {
e.preventDefault();
if (e.target.files !== null) {
let reader = new FileReader();
let file = e.target.files[0];
reader.onloadend = () => {
setPostImgPreview(reader.result ? .toString())
}
reader.readAsDataURL(file);
}
}
const handlePost = (e: React.MouseEvent < HTMLButtonElement, MouseEvent > ) => {
e.preventDefault();
const postNameVal = postname.current ? .value
const postContentVal = postcontent.current ? .value
if (postNameVal && postContentVal && postImgPreview) {
const base64 = postImgPreview.split(',')[1];
postImgurImage(base64, currentUser ? .username ? ? '', postContentVal).then(data => {
console.log(data);
})
}
}
<input type="file" name="post-image" id="post-image" accept="image/x-png,image/jpeg" onChange={e=> handleImg(e)} />
<button className="post-button" onClick={handlePost}>Post</button>
Related
I am getting my base64 urls and they are correct because if I send only one image its uploaded correctly to cloudinary but when sending multiple images Ii get an error 'ENAMETOOLONG' with error number 4064
here is my graphql resolver
createEvent: async (args: any, req: any) => {
if (!req.isAuth) {
throw new Error("Unauthenticated!!!!");
}
let imagesArr: any[] = [];
for (let i = 0; i < args.eventInput.images.length; i++) {
const result = await cloudinary.uploader.upload(
args.eventInput.images[i],
{
public_id: `${args.eventInput.title}${new Date(
args.eventInput.date
)}${i}`,
folder: "Eventers",
allowedFormats: ["jpeg", "png", "jpg"],
}
);
console.log(result.url, result.public_id);
imagesArr.push({ public_id: result.public_id, url: result.secure_url });
}
const event = new Event({
title: args.eventInput.title,
description: args.eventInput.description,
price: +args.eventInput.price,
date: new Date(args.eventInput.date),
category: args.eventInput.category,
brief: args.eventInput.brief,
tickets: +args.eventInput.tickets,
images: [...imagesArr],
author: req.userId,
});
let createdEvent;
try {
const result = await event.save();
createdEvent = transformEvent(result);
const author = await User.findById(req.userId);
if (!author) {
throw new Error("User not found.");
}
author.createdEvents.push(event);
await author.save();
return createdEvent;
} catch (error) {
console.log(error);
throw error;
}
},
here is the response i get when trying to submit multiple base64 urls
message: "Unexpected error value: { error: { errno: -4064, code: \"ENAMETOOLONG\", syscall: \"open\", path: \"C:\\\\Users\\\\user\\\\Desktop\\\\graphQl maximillian yt course\\\\bookingEvents\\\\backend\\\\data:image\\\\jpeg;base64,\\\\9j\\\\4AAQSkZJRgABAQAAAQABAAD\\\\2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj\\\\2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj\\\\wAARCAQIAkUDASIAAhEBAxEB\\\\8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL\\\\8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6\\\\8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL\\\\8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uP…"
and here is how i transform the images to base
const fileOnChangeHandler = async (e: ChangeEvent<HTMLInputElement>) => {
let files = Array.from(e.target.files!);
files.forEach((file: any) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = async () => {
setImageLinks((prevArr: any) => [...prevArr, reader.result]);
};
});
};
and here is how i send the data to the back end
export const fetchAsyncCreateEvents = createAsyncThunk(
"Events/fetchAsyncCreateEvents",
async (eventInput: Event) => {
const {
title,
category,
description,
brief,
price,
date,
tickets,
images,
} = eventInput;
const { data } = await axios.post<Event>(
API,
{
query: `
mutation{
createEvent(eventInput:{title:"${title}",category:"${category}",description:"""${description}""",brief:"${brief}",price:${price},date:"${date}",tickets:${tickets},images:"${images}"}){
author{
email
}
}
}
`,
},
{
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + localStorage.getItem("token"),
},
}
);
return data;
}
);
I've tried alot of things like adding .replace(/(\r\n|\n|\r)/gm,"") to the for loop at each image array index but it didnt work
and here is one of the base 64 urls
"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAQIAkUDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4"
I deleted more than half of the url so I could submit the question.
i solved the problem it was so simple the problem is i am sending the array of images base64 in a wrong way in graphql mutation
i was sending it with a quotation wrapping it and it turned out you have to use quotations only for strings and for arrays you should json.stringify
export const fetchAsyncCreateEvents = createAsyncThunk(
"Events/fetchAsyncCreateEvents",
async (eventInput: Event) => {
const {
title,
category,
description,
brief,
price,
date,
tickets,
images,
} = eventInput;
const { data } = await axios.post<Event>(
API,
{
query: `
mutation{
createEvent(eventInput:{title:"${title}",category:"${category}",description:"""${description}""",brief:"${brief}",price:${price},date:"${date}",tickets:${tickets},images:${JSON.stringify(images)}}){
author{
email
}
}
}
`,
},
{
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + localStorage.getItem("token"),
},
}
);
return data;
}
);
I am having trouble uploading an image to the db after cropping. I am able to upload the file on Postman, but can't figure out how to do it after cropping and getting it returned as a base64.
Here is my route that works with uploading a raw file, but not the base64:
exports.uploadProfileMedia = (req, res) => {
const BusBoy = require("busboy")
const path = require("path")
const os = require("os")
const fs = require("fs")
let mediaFileName
let mediaToBeUploaded = {}
let generatedToken = uuidv4()
const busboy = new BusBoy({ headers: req.headers })
busboy.on("file", (fieldname, file, filename, encoding, mimetype) => {
console.log(file, "before")
if (
mimetype !== "image/jpeg" &&
mimetype !== "image/png" &&
mimetype !== "image/heic"
) {
return res.status(400).json({ error: "Wrong file type submitted" })
}
const mediaExtension = filename.split(".")[
filename.split(".").length - 1
]
mediaFileName = `${Math.round(
Math.random() * 100000000000
).toString()}.${mediaExtension}`
const filepath = path.join(os.tmpdir(), mediaFileName)
mediaToBeUploaded = { filepath, mimetype }
file.pipe(fs.createWriteStream(filepath))
console.log(file, "after")
})
busboy.on("finish", () => {
admin
.storage()
.bucket()
.upload(mediaToBeUploaded.filepath, {
resumable: false,
metadata: {
metadata: {
contentType: mediaToBeUploaded.mimetype,
firebaseStorageDownloadTokens: generatedToken
}
}
})
.then(() => {
const mediaUrl = `https://firebasestorage.googleapis.com/v0/b/${firebaseConfig.storageBucket}/o/${mediaFileName}?alt=media&token=${generatedToken}`
return db
.doc(`/users/${req.user.username}`)
.update({ mediaUrl })
})
.then(() => {
return res
.status(201)
.json({ message: "Media uploaded successfully" })
})
.catch((err) => {
console.error(err)
return res.status(500).json({ error: err.code })
})
})
busboy.end(req.rawBody)
}
Here is where I pass in a base64 after cropping:
const uploadProfileMedia = (formData) => {
axios.defaults.headers.common["Authorization"] = localStorage.getItem(
"FBIdToken"
)
axios
.post("/api/user/media", formData)
.then((res) => {})
.catch((err) => console.log(err))
console.log(formData, "form")
}
Here is a snippet of the above console.log():
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDREN
Here is the function which calls the uploadProfileMedia():
const showCroppedImage = useCallback(async () => {
console.log(imageSrc, "imgsrc")
try {
const croppedImage = await getCroppedImg(
imageSrc,
croppedAreaPixels
)
setCroppedImage(croppedImage)
uploadProfileMedia(croppedImage)
console.log(croppedImage, "showcroppedImage")
} catch (e) {
console.error(e)
}
}, [imageSrc, croppedAreaPixels])
I have an Axios get request I'd like to cancel upon an event but it doesn't seem to work.
// user.services.js
searchFAQS(query) {
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
source.cancel('Operation cancelled by user')
return axios.get(
authHeader.getApiUrl() + '/api/v1/search_faqs',
{
cancelToken: source.token,
params: {
query: query
}
}
)
}
// ClassComponent
onChangeQuery = (e) => {
if (e.target.value === "") {
this.setState({
fFaq: "",
query: e.target.value
})
} else {
UserServices.searchFAQS().cancel()
this.setState({query: e.target.value},
() => UserServices.searchFAQS(this.state.query)
.then(resp => {
this.setState({
fFaq: resp.data,
fGroups: resp.data.map(f => f.group).filter((value, index, self) => self.indexOf(value) === index)
})
}))
}
}
I read the cancellation part for the Axios documentation, which is what led me to the attempt above, but it doesn't seem to be canceling after observing the requests from developer tools.
searchFAQS(query) {
const CancelToken = axios.CancelToken;
.....
new CancelToken is creating on every searchFAQS call, so it will not get cancel because everytime it's a new token
change as below
let token = null; // define cancel token outside the search fn, then it will not recreate on every call
searchFAQS(query) {
if (token !== null) {
token();
}
...
const { CancelToken } = axios;
...
return axios.get(
authHeader.getApiUrl() + '/api/v1/search_faqs',
{
cancelToken: new CancelToken(function executor(cancellableFn) {
token = cancellableFn;
}),
params: {
query: query
}
}
....
On my understanding you solution should looks like this:
// user.services.js
async searchFAQS(query, source = '') {
const search = axios.get(
authHeader.getApiUrl() + '/api/v1/search_faqs',
{
cancelToken: source.token,
params: {
query: query
}
}
);
if (source /* change to your needs, actualy it cancels all requests */) {
source.cancel('Ok, its just canceled!');
}
return await search.data;
}
// ClassComponent
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
onChangeQuery = (e) => {
if (e.target.value === "") {
this.setState({
fFaq: "",
query: e.target.value
})
} else {
UserServices.searchFAQS("", source)
this.setState({query: e.target.value},
() => UserServices.searchFAQS(this.state.query, source)
.then(resp => {
this.setState({
fFaq: resp.data,
fGroups: resp.data.map(f => f.group).filter((value, index, self) => self.indexOf(value) === index)
})
}))
}
}
I am performing chat module using Rest Apis in React native app i want to make it real time how can i use Socket.io with it.here is my code where i am fetching message and send messages with a person how to make all this real time with socket.io. Please help
componentDidMount() {
this.fetchMessages();
}
fetchMessages = async () => {
const Pid = await AsyncStorage.getItem("projectUid");
const { params } = this.props.navigation.state;
const response = await fetch(
CONSTANT.BaseUrl + "chat/list_user_messages?current_id=" + Pid + "&reciver_id=" + params.receiver_id + "&msg_id=" + params.message_id
);
const json = await response.json();
if (Array.isArray(json) && json[0] && json[0].type && json[0].type === 'error') {
this.setState({ fetchMessageDetail: [] ,isLoading:false}); // empty data set
} else {
this.setState({ fetchMessageSenderDetail: json.chat_sidebar , isLoading:false });
this.setState({ fetchMessageDetail: json.chat_nodes , isLoading:false });
}
};
SendMessage = async () => {
const { message } = this.state;
const { params } = this.props.navigation.state;
const Uid = await AsyncStorage.getItem("projectUid");
if (message == "") {
//alert("Please enter Email address");
this.setState({ email: "Please add message" });
} else {
axios
.post(
CONSTANT.BaseUrl + "chat/sendUserMessage",
{
sender_id: Uid,
receiver_id: params.receiver_id,
message:message,
}
)
.then(async response => {
this.setState({
message:''
})
this.fetchMessages();
})
.catch(error => {
console.log(error);
});
}
Keyboard.dismiss();
};
I am trying to upload images to an S3 bucket with react and expressjs. When I attempt to upload the image I get a 501 Not Implemented Error. I am using axios to contact the end point I created in the server code.
My react code:
class FileUpload extends Component {
state = {
file: null
};
submitFile = (event) => {
event.preventDefault();
const formData = new FormData();
formData.append('file', this.state.file[0]);
axios.post(`test-upload`, formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(response => {
// handle your response;
}).catch(error => {
// handle your error
});
}
handleFileUpload = (event) => {
this.setState({file: event.target.files});
}
render () {
return (
<form onSubmit={this.submitFile}>
<input label='upload file' type='file' onChange=
{this.handleFileUpload} />
<button type='submit'>Send</button>
</form>
);
}
}
export default FileUpload;
My server code:
const uploadFile = (buffer, name, type) => {
const params = {
ACL: 'public-read',
Body: buffer,
Bucket: process.env.S3_BUCKET,
ContentType: type.mime,
Key: `${name}.${type.ext}`
};
return s3.upload(params).promise();
};
app.use('/', (req,res) =>{
res.send(JSON.stringify({ greeting: `Hello!` }));
});
// Define POST route
app.post('/test-upload', (request, response) => {
const form = new multiparty.Form();
form.parse(request, async (error, fields, files) => {
if (error) throw new Error(error);
try {
const path = files.file[0].path;
const buffer = fs.readFileSync(path);
const type = fileType(buffer);
const timestamp = Date.now().toString();
const fileName = `bucketFolder/${timestamp}-lg`;
const data = await uploadFile(buffer, fileName, type);
return response.status(200).send(data);
} catch (error) {
return response.status(400).send(error);
}
});
});
This was done by following a guide on the internet but there seems to be something missing that I just can't figure out.
Figured it out in the end,
axios.post(/test-upload,
should have been
axios.post(http://localhost:3000/test-upload,