Using FileTransfer plugin pass data to next request in for loop - javascript

I have a image upload Request with a param. I want to send response from 1st request to all next requests inside for loop.
Page.page.ts
//function to take Photos
takePhoto() {
this.camera.takePhoto().then((res: any) => {
res.map((v) => {
this.uploadMedia(v.fullPath, v.fullPath.split('/').pop())
})
})
}
// function to upload Photos
uploadMedia(path, type) {
this.imgLoader = true;
this.camera.uploadFileMedia(path, 'UploadImage', type, this.postId).then((res: any) => {
if (res.status == true) {
this.postId = res.data.post_id; // I want to pass this postId to All other Requests.
this.userImages.push({ img: res.data});
}
})
}
Camera Service .ts
uploadFileMedia(path: string, url: string, fileType: string, post_id): Promise<any> {
const fileTransfer: FileTransferObject = this.transfer.create();
let options: FileUploadOptions = {
fileKey: 'images',
fileName: fileType,
params: {post_id: post_id }
}
return new Promise(resolve => {
fileTransfer.upload(path, url, options).then((data) => {
resolve(res)
}, (err) => {
})
})
}

Solved it by Converting my UploadFileMedia() from Promise to Observable in my camera.service.ts
UploadFileMedia(path: string, url: string, fileType: string, post_id): Observable<any> {
const fileTransfer: FileTransferObject = this.transfer.create();
let options: FileUploadOptions = {
fileKey: "images",
fileName: fileType,
chunkedMode: false,
params: { post_id: post_id }
};
return new Observable(result => {
fileTransfer.upload(path, url, options).then((data) => {
let res = JSON.parse(data.response);
result.next(res);
}, err => {
result.error(err);
});
});
}
and inside my page.ts:
takePhoto = async () => {
this.camera.takePhoto().then(async (res: any) => {
for (let v = 0; v < res.length; v++) {
await new Promise((resolve, reject) => {
this.camera.UploadFileMedia(res[v].fullPath, 'UploadImage', res[v].fullPath.split('/').pop(), this.postId).subscribe((res: any) => {
console.log(res);
if (res.status == true) {
this.postId = res.data.post_id;
this.userImages.push({ img: res.data});
resolve(true)
} else {
reject();
}
})
})
}
})
}
Idea taken From:
Another Answer for Same Problem

Related

calling an api inside map function In node Js

const processInboundEmailAttachment = async (files: any[]): Promise<any[]> => {
const attachments = []
await Promise.all(
files.map(async (file) => {
try {
let response = null
response = await axios.get(file.url, {
headers: {
Accept: "message/rfc2822"
},
auth: {
username: "api",
password: "api-key"
},
responseType: "stream"
})
if (response && response.data) {
response.data.pipe(concat(async data => {
try {
const mediaUrl = await uploadToFirestore(file["content-type"], data, file.name)
attachments.push({
name: file.name,
url: mediaUrl,
id : uuidv4()
})
} catch (error) {
console.log("err", error);
}
}));
}
} catch (err) {
log.error(err)
}
})
)
return attachments // from here this return initial attachments [] array
}
const uploadAttachment = async () => {
const attachment = await processInboundEmailAttachment(JSON.parse(attach))
console.log("attachment",attachment);
// I want updated pushed attachment array here but I got [] initial decalare value
}
app.get("/uploadAttachment", uploadAttachment)
In attachment console log I got [] array , It's return initial assign values of array.
It's not wait for API response and newly pushed array.
I think There Is an some issue in Promise , It's not wait for updated array , It's
return directly initialy attachment array
Thank you for Help In advnace
Looks like it is not waiting for uploadFirestore response. You can cut down your function something like below and wrap it custom promise.
const processInboundEmailAttachment = async (files: any[]): Promise<any[]> => {
const getFileUploadedResult = function(file) {
return new Promise(async (resolve, reject) => {
try {
let response = null
response = await axios.get(file.url, {
headers: {
Accept: "message/rfc2822"
},
auth: {
username: "api",
password: "api-key"
},
responseType: "stream"
})
if (response && response.data) {
response.data.pipe(concat(async data => {
try {
const mediaUrl = await uploadToFirestore(file["content-type"], data, file.name)
resolve({
name: file.name,
url: mediaUrl,
id : uuidv4()
})
} catch (error) {
reject(err)
}
}));
}
} catch (err) {
log.error(err)
reject(err)
}
})
}
return Promise.all(
files.map(async (file) => {
return getFileUploadedResult(file)
})
)
}
const uploadAttachment = async () => {
const attachment = await processInboundEmailAttachment(JSON.parse(attach))
console.log("attachment",attachment);
// I want updated pushed attachment array here but I got [] initial decalare value
}
app.get("/uploadAttachment", uploadAttachment)

How do I need to collect my data in the object for post request?

I just want to send request, but in the end of function my object is{img:'',text: ''}.
I expect to get .jpg file name in obj.img and text inside .txt file in obj.text. So here we go:
Maybe it's something about scope. I don't know.
const path = require('path');
const fs = require('fs');
const request = require('request');
const axios = require('axios');
let shortcode = '';
async function getData() {
const obj = {
img: '',
text: '',
};
await fetch('http://127.0.0.1:8000/api')
.then(response => response.json())
.then(data => (shortcode = data[data.length - 1].shortcode));
fs.readdir(
`path/${shortcode}`,
(err, data) => {
if (err) {
throw err;
}
data.forEach(file => {
if (path.extname(file) === '.jpg') {
obj.img = file;
} else if (path.extname(file) === '.txt') {
fs.readFile(
`path/${shortcode}/${file}`,
'utf-8',
(err, data) => {
if (err) {
throw err;
}
obj.text = data;
console.log(data);
},
);
}
});
},
);
console.log(obj);
await fetch('http://127.0.0.1:8000/instaData', {
method: 'POST',
body: JSON.stringify({
img: obj.img,
text: obj.text,
}),
headers: {
'Content-Type': 'application/json;charset=utf-8',
},
});
}
getData();

Get Out of a TextDecoderStream() from NodeJS

When I send an error message from my express nodejs app using res.status(400).send(err.stack);, I cannot seem to get out of the decoder stream I setup on the receiving end.
Here is my code in the browser (limited to the fetch portion):
fetch("/the/url", {
method: "POST",
body: formData,
}).then(response => {
if (response.status === 200) {
return response.blob().then((data) => {
return data;
});
} else {
return new Promise((resolve, reject) => {
let err_message = "";
let reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
reader.read().then(({done, value}) => {
// When no more data needs to be consumed, close the stream
if (done) {
reject(err_message);
return;
}
// Enqueue the next data chunk into our target stream
err_message += value;
});
}).then((res) => {
return (res)
}).catch((err) => {
return (err)
});
}
}).then((res) => {
console.log(res)
}).catch((err) => {
console.log(err)
});
I have put breakpoints on all subsequent then and catch but it never resolves/rejects.
Appreciate any pointers.
In case it's helpful to someone, you need to make a recursive call to the same function to break out properly.
As per the following :
fetch("/the/url", {
method: "POST",
body: formData,
}).then(response => {
if (response.status === 200) {
return response.blob().then((data) => {
return data;
});
} else {
return new Promise((resolve, reject) => {
let err_message = "";
let reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
reader.read().then(function processText({done, value}) {
// When no more data needs to be consumed, close the stream
if (done) {
reject(err_message);
return;
}
// Enqueue the next data chunk into our target stream
err_message += value;
return reader.read().then(processText);
});
}).then((res) => {
return (res)
}).catch((err) => {
return (err)
});
}
}).then((res) => {
console.log(res)
}).catch((err) => {
console.log(err)
});
from https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream/getReader

Where to place the `axios.interceptor`? In a separate service in create-react-app?

I have this directory structure:
//app
//public
//index.html
//assets
//favicon.ico
//src
//components
//App.js
//index.js
Where to place the interceptor ? Should I create a separate directory with services and import it into the file App.js?
Interceptor
axios.defaults.baseURL = localStorage.getItem('domain');
let isRefreshing = false;
let failedQueue = [];
const processQueue = (error, token = null) => {
failedQueue.forEach(prom => {
if (error) {
prom.reject(error);
} else {
prom.resolve(token);
}
})
failedQueue = [];
}
axios.interceptors.response.use(function (response) {
document.body.classList.remove('loading-indicator');
return response;
}, error => {
const originalRequest = error.config;
if (error.response.status === 401 && !originalRequest._retry) {
if (isRefreshing) {
return new Promise((resolve, reject) => {
failedQueue.push({resolve, reject})
}).then(token => {
originalRequest.headers["Authorization"] = "Bearer " + token;
return axios(originalRequest);
}).catch(err => {
return Promise.reject(err);
})
}
originalRequest._retry = true;
isRefreshing = true;
const data = qs.stringify({
grant_type: "refresh_token",
client_id: "****",
client_secret: "******",
refresh_token: window.localStorage.getItem("token")
const config = {
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
}
return new Promise(function (resolve, reject) {
axios({
method: "post",
url: "/oauth2/token",
data,
config
})
.then(({data}) => {
const token = data;
})
.catch((err) => {
processQueue(err, null);
reject(err);
})
.then(() => { isRefreshing = false })
})
}
return Promise.reject(error);
});

Search for particular results with a certain string in GraphQL

I want to search with my query getFoodType to return results based on whether the foodType of particular restaurant/takeaway is a "Chicken","Pizza" etc
Like this foodType: "Chicken"
I've tried using arguments and mongoDB filters (it's a MongoDB server) but no luck.
Schema
const EaterySchema = new Schema({
name: {
type: String,
required: true
},
address: {
type: String,
required: true
},
foodType: {
type: String,
required: true
}
});
My Schema Types
type Eatery {
id: String!
name: String!
address: String!
foodType: String!
}
type Query {
eatery(id: String!): Eatery
eateries: [Eatery]
getFoodType(foodType: String): [Eatery]
}
My Resolver
getFoodType: () => {
return new Promise((resolve, reject) => {
Eatery.find({})
.populate()
.exec((err, res) => {
err ? reject(err) : resolve(res);
});
});
},
Current Query in Apollo Playground
{
getFoodType (foodType: "Chicken") {
id
name
address
foodType
}
}
I essentially want to return all the results with "Chicken" as a the foodType. Something like foodType: "Chicken".
First, you need to get the value of the foodType to be queried in Resolver
const resolvers = {
Query: {
getFoodType: (_, args) => {
const { foodType } = args
...
},
},
}
Then use foodType when querying
Eatery.find({ foodType })
Finally need to return the result
new Promise((resolve, reject) => {
return Eatery.find({ foodType })
.populate()
.exec((err, res) => {
err ? reject(err) : resolve(res)
})
})
Complete example
const resolvers = {
Query: {
getFoodType: (_, args) => {
const { foodType } = args
return new Promise((resolve, reject) => {
return Eatery.find({ foodType })
.populate()
.exec((err, res) => {
err ? reject(err) : resolve(res)
})
})
},
},
}
Use the async/await
const resolvers = {
Query: {
getFoodType: async (_, { foodType }) => {
try {
const eaterys = await Eatery.find({ foodType }).populate()
return eaterys
} catch (e) {
// Handling errors
}
},
},
}

Categories

Resources