Ionic: Android - Image from Camera is not uploading to server with FileTransfer - ionic-framework

I am trying to pick a image from photo gallary and upload to the server.
I have a PHP script to receive the file and copy to the server location. I have tested this script with Postman. It works perfectly.
I have a provider to upload the image to the PHP script. The code snippet for upload function is below.
upload(imageData) {
let posturl = APIURL + 'message/upload';
const fileTransfer: FileTransferObject = this.transfer.create();
let options1: FileUploadOptions = {
fileKey: 'file',
fileName: 'name.jpg',
headers: {}
}
return new Promise((resolve, reject) => {
fileTransfer.upload(imageData, posturl, options1)
.then((data) => {
resolve(data);
}, (err) => {
alert(JSON.stringify(err));
reject(err.message);
});
});
}
TS code for picking the image and calling the provider is:
pickimage()
{
const options: CameraOptions = {
quality: 100,
destinationType: this.camera.DestinationType.FILE_URI,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
sourceType : this.camera.PictureSourceType.PHOTOLIBRARY
};
this.camera.getPicture(options).then((imageData) => {
this.imageURI = imageData;
}, (err) => {
// Handle error
});
}
TS code for picking the image and calling the provider:
this.messageService.upload(this.imageURI).then((result) => {
this.responseData = result;
if (this.responseData.status=="success")
{
this.mediaurl = this.responseData.mediaurl;
}
},
(err) => {
alert("Not able to send image");
});
The file is not getting uploaded. The alert(JSON.stringify(err)) in the provider returns null.
I am testing this with DevApp.
Any help?

Related

Error while Uploading Image to Mongodb using Gridfs and Graphql

Im trying to upload an image to mogodb using graphql and gridfs. When trying to do i'm facing a error :
" JSON Parse error: Unexpected identifier "This" "
I'm not sure what I've done wrong in the code.
Can anyone help me figure out where I've gone wrong in the implementation
This is the part for uploading Image
const selectProfilePic = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
aspect: [2, 3],
quality: 1,
});
handleImagePicked(result);
};
const handleImagePicked = async (result: ImagePicker.ImagePickerResult) => {
try {
if (result.cancelled) {
alert("Upload cancelled");
return;
} else {
console.log("In HERE ::: 76");
const lastIndex = result.uri.lastIndexOf("/") + 1;
console.log(result);
const file = new ReactNativeFile({
uri: result.uri,
name: result.uri.substring(lastIndex),
type: "image/png",
});
setAvatar(result.uri);
console.log(file); // This result is getting printed.
await singleUpload({ // I think the Upload function is not getting called.
variables: {
file,
},
});
}
} catch (e) {
console.log(e);
alert("Upload failed");
}
};
Resolver Function
singleUpload: async (_, { file }, context) => {
const {db, user, hhhhhh, gfs} = context;
console.log(gfs);
const res = uploadFn({ file },gfs);
console.log(res);
Apollo.tsx File
const uploadLink = createUploadLink({
uri: CLIENT_HTTP_URI,
});
// splitLink is defined here
export const client = new ApolloClient({
link: ApolloLink.from([authLink, splitLink]),
cache: new InMemoryCache(),
});
Have created StorageEngine.js File with this code
const storage = new GridFsStorage({
url: DB_URI,
file: (req, file) => {
return new Promise((resolve, reject) => {
crypto.randomBytes(16, (err, buf) => {
if(err) { return reject(err); }
const fileName = buf.toString('hex') + path.extname(file.originalname);
const fileInfo = {
fileName,
bucketName: 'uploads'
};
resolve(fileInfo);
});
});
}
});
const upload = multer({storage});
const uploadFn = async ({file}, bucket) => {
console.log(file);
const { createReadStream, name, type, encoding } = await file;
const uploadStream = bucket.openUploadStream(name, {
contentType: type
});
// console.log(uploadStream);
return new Promise((resolve, reject) => {
createReadStream()
.pipe(uploadStream)
.on('error', reject)
.on('finish', () => {
console.log(uploadStream.id);
resolve(uploadStream.id);
});
});
}

html2canvas not rendering on safari

I'm trying to save image from canvas drawing, it works 2-3 times giving me datatourl i save in an hidden input field, then it stops going thru for some reason, it's not rendered and i can't get base64 in input field anymore.
function downloadClick() {
self.resetTransformer();
setTimeout(async function () {
const url = await createImage();
if (url) downloadImage(url, "draw.jpg");
if (url) await saveImage(url);
}, 200)
}
async function createImage() {
const {default: html2canvas} = await import('html2canvas');
self.resetTransformer();
return html2canvas(self.container.querySelector('.konvajs-content'), {
backgroundColor: null,
scrollY: -window.pageYOffset,
logging: true,
useCORS: true
})
.then(canvas => {
return canvas.toDataURL("image/png");
})
.catch(error => console.error(error));
}
function downloadImage(url, name) {
const link = document.createElement('a');
link.download = name;
link.href = url;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
async function saveImage(img) {
let imgForm = document.querySelector('#drawImage');
let hiddenInput = document.querySelector('#game-image');
hiddenInput.value = img;
imgForm.setAttribute('crossorigin', 'anonymous');
imgForm.setAttribute('data-src', img);
imgForm.setAttribute('src', img);
}
}

UI Doesn't update after SWR data does NEXTJS

I have a simple project going on and it is smoothly working but I have failed to add a item delete button. My post request to add items is perfectly working but my delete items doesn't work. I chose to go with post instead of delete because of my api structure.
Repo: https://github.com/berkaydagdeviren/rl-revenue-calculator
const handleClick = async (e) => {
e.preventDefault();
console.log(totalCredit, 'total credit before')
setTotalCredit([...totalCredit, credit])
console.log(ref, 'refFFFFFFF')
const currentDate = ref.current
const options = {
method: "PUT",
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify(
{ date: currentDate, credits: credit }
)
}
var responseClone;
fetch(`api/hello?date=${ref.current}`, options)
.then(res => {
responseClone = res.clone();
return res.json()
}).then(data => {
console.log(data, 'data')
}).then(function (data) {
// Do something with data
}, function (rejectionReason) { // 3
console.log('Error parsing JSON from response:', rejectionReason, responseClone); // 4
responseClone.text() // 5
.then(function (bodyText) {
console.log('Received the following instead of valid JSON:', bodyText); // 6
});
});
setCredit(0)
}
This is working perfectly fine but this does not;
const handleItemDelete = async itemToBeDeleted => {
console.log(itemToBeDeleted, "itemTobeDeleted")
const options = {
method: "PUT",
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify(
{ date: ref.current, index: itemToBeDeleted }
)
}
var responseClone;
await fetch(`api/hello?date=${ref.current}`, options)
.then(async res => {
responseClone = res.clone();
console.log(res, "res")
return await res.json()
// I used this to read server's response when it was giving parsing JSON error
}).then(data => {
console.log(data, 'data')
}).then(function (data) {
// Do something with data
}, function (rejectionReason) { // 3
console.log('Error parsing JSON from response:', rejectionReason, responseClone); // 4
responseClone.text() // 5
.then(function (bodyText) {
console.log('Received the following instead of valid JSON:', bodyText); // 6
});
});
const newTotalCredit = await data.find(item => item.date == ref.current).credits
setTotalCredit(newTotalCredit)
console.log("STATE UPDATED BEFORE DATA")
}
This is where I reference handleItemDelete to;
credit.map((item, index) => {
return (
item > 0 ?
React.Children.toArray(
<div>
<span style={{ color: 'green' }}> +{item}C </span>
<button onClick={() =>handleItemDelete(index)}>
X
</button>
</div>
)
:
null
)
})
}
And this is how I handle put request, again I can see that mongodb is updated after refresh but because ui didn't totalCredits' indexes are messed up and results in either no deletion or false deletion.
handler.put(async (req, res) => {
let data = req.body
console.log(typeof(data))
if (data.index) {
let {date, index} = req.body
console.log(data.index, "data.index")
await req.db.collection('credits').update({date: date}, {$unset: {["credits."+ index] : 1}})
await req.db.collection('credits').update({date: date}, {$pullAll: {credits: [null]}})
}
await req.db.collection('credits').updateOne({date: data.date}, {$push: {credits: data.credits}})
res.json(data)
})
I use SWR right in the index.js Home component
export default function Home()
{
const [totalCredit, setTotalCredit] = useState([])
const [credit, setCredit] = useState('')
const ref = useRef(null);
const [date, setDate] = useState(null);
const { data } = useSWR('/api/hello', async (url) => {const response = await axios.get(url);
return response.data; },
{ refreshInterval: 1000, revalidateOnMount: true });
Sorry if I'm not clear or providing wrong pieces of code please let me know. Thank you in advance!
your options in handleDeleteItem:
const options = {
method: "PUT",
headers: {
'Content-type': 'application/json'
},
Should not method be DELETE? You are sending PUT request instead of DELETE

Axios get request with parameter is not working

I am passing a parameter to the axios get request. It works on postman properly but does not work with my code. I don't know where I am making a mistake.
I want only one specific data from db but I am receiving all the data in available in the collection. But with postman I get the desired data
backend route :
router.get('/displayUser', (req,res) => {
const query = user = req.body ;
Services.find(query)
.exec((err, services) => res.json(services))
})
axios call : I tried two different ways and both didn't work
method 1:
getData: async function () {
const user = this.userId
console.log(user)
let res = await axios.get('http://localhost:5000/api/services/displayUser' , { params: { user }})
console.log(res.data);
}
method 2:
getData: async function () {
var data = JSON.stringify({"user":this.userId});
console.log(data)
var config = {
method: 'get',
url: 'http://localhost:5000/api/services/displayUser',
headers: {
'Content-Type': 'application/json'
},
data : data
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
}
When I get the data in console I am getting all 3 objects available in collection instead of the specific one related to the user Id
Screenshot
But in postman It works as desired
screenshot
I do this as following:
when I need a get :
app.get('/detail/:id', function (req, res) {
//console.log(req.params.id);
var url=urlDetail + "/" + req.params.id;
axios.get(url)
.then(function (response) {
// result=response.data;
res.render('database', { title: 'Detail' , dbs: response.data ,Version:pjson.version});
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
//console.log("ici always");
});
});
and when i need to post (req.body is a json):
app.post('/carto/demande', function (req, res) {
let data;
console.log(req.params);
console.log(req.body);
var url=urlCartoDemande;
axios.post(url,req.body)
.then(function (response) {
data=response.data;
res.render('carto', { title : 'Demande' ,Version:pjson.version,mode:"resultat",data:data } );
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
});

How to share a video directly to facebook/instagram through a link as video which can be directly played using react-native

How to share a video directly to Facebook/Instagram/twitter through a link using react-native. I am using react-native-share to share videos on Instagram/Facebook but that is getting shared as a link, but I want to share them as a video as TikTok does.
How can I achieve that? I know it is able by converting it to base 64, so are there any libraries which convert links to base 64 directly? Else I would need to download it first then retrieve it and then convert to base 64 then share it.
Please help!
Will Answer how I did it if some one needs the complete code:
shareURL = async (socialMedia) => {
let facebook = socialMedia === 'facebook'
let twitter = socialMedia === 'twitter'
const { video, uploadingStatus } = this.state;
this.setState({ isSliderModalVisible: true }, async () => {
let uploadOptions = { fileCache: true, appendExt: 'mp4', timeout: 60000, indicator: true, IOSBackgroundTask: true, }
const res = await RNFetchBlob.config(uploadOptions).fetch('GET', video, {})
.progress((received, total) => {
this.setState({ uploadingStatus: (received / total) * 100 })
console.log('Progress', (received / total) * 100);
})
const filePath = res.path(); //to delete video
const base64String = await res.base64();
const url = `data:video/mp4;base64,${base64String}`;
await RNFetchBlob.fs.unlink(filePath); //deleted the video from path of celebfie.
this.setState({ isSliderModalVisible: false })
setTimeout(() => {
const shareOptions = {
title: 'Celebfie',
message: hashtags,
subject: 'Sharing my intro video which I recorded in Celebfie.',
url: url,
type: 'video/mp4',
social: facebook ? Share.Social.FACEBOOK : twitter ? Share.Social.TWITTER : Share.Social.INSTAGRAM
};
Share.shareSingle(shareOptions).then((res) => this.setState({ sharedVideoToSocialNetwork: true }))
.catch((err) => { Global.customToast('Video sharing failed.', 'failure') })
})
}, 1000);
}
Answering my own question here it is how it works :
shareURL = async (socialMedia) => {
let facebook = socialMedia === 'facebook'
let twitter = socialMedia === 'twitter'
const { video, uploadingStatus } = this.state;
this.setState({ isSliderModalVisible: true }, async () => {
let uploadOptions = { fileCache: true, appendExt: 'mp4', timeout: 60000, indicator: true, IOSBackgroundTask: true, }
const res = await RNFetchBlob.config(uploadOptions).fetch('GET', video, {})
.progress((received, total) => {
this.setState({ uploadingStatus: (received / total) * 100 })
console.log('Progress', (received / total) * 100);
})
const filePath = res.path(); //to delete video
const base64String = await res.base64();
const url = `data:video/mp4;base64,${base64String}`;
await RNFetchBlob.fs.unlink(filePath); //deleted the video from path of Sexy lady.
this.setState({ isSliderModalVisible: false })
setTimeout(() => {
const shareOptions = {
title: 'Sexy Lady',
message: hashtags,
subject: 'Sharing my intro video which I recorded in Celebfie.',
url: url,
type: 'video/mp4',
social: facebook ? Share.Social.FACEBOOK : twitter ? Share.Social.TWITTER : Share.Social.INSTAGRAM
};
Share.shareSingle(shareOptions).then((res) => this.setState({ sharedVideoToSocialNetwork: true }))
.catch((err) => { Global.customToast('Video sharing failed.', 'failure') })
})
}, 1000);
}
you can do like this :
Share.open(
{
message: `I have successfully Completed this course`,
title: 'Share',
url: 'file:///documents..',
type: 'video/mp4',
},
{
// Android only:
dialogTitle: 'Share',
// iOS only:
excludedActivityTypes: ['com.apple.UIKit.activity.PostToTwitter'],
},
);