I am trying to upload a csv/xlxs file in angular 2 but whenever i submit the file, i get an exception file could not upload. please try again from my backend although it works fine on postman. What could be wrong in my code?
//service
constructor (private authenticate:AuthenticationService) {
this.filetrack = Observable.create(observer => {
this.progressObserver = observer
}).share();
}
SendRequest (url: string, params: string[], files: File[]) {
return Observable.create(observer => {
let formData: FormData = new FormData(),
xhr: XMLHttpRequest = new XMLHttpRequest();
for (let i = 0; i < files.length; i++) {
formData.append("uploads[]", files[i], files[i].name);
}
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
observer.next(JSON.parse(xhr.response));
observer.complete();
} else {
observer.error(xhr.response);
}
}
};
xhr.upload.onprogress = (event) => {
this.progress = Math.round(event.loaded / event.total * 100);
this.progressObserver.next(this.progress);
};
xhr.open('POST', url, true);
xhr.setRequestHeader('Authorization', 'Bearer ' + this.authenticate.user_token);
xhr.send(formData);
});
}
}
//component
export class FileUploadComponent {
constructor(private service:FileUploadService) {
this.service.filetrack.subscribe(
data => {
console.log('progress = '+data);
});
}
onChange(event) {
console.log('onChange');
let files = event.target.files;
console.log(files);
this.service.SendRequest('http://localhost:8000/register/v1/file/country', [], files).subscribe(() => {
console.log('sent');
});
}
}
You have to set another header to be able to upload a file:
xhr.setRequestHeader("Content-Type", "multipart/form-data");
Related
I'm building social media application using node js and react js, I have problem when it comes to video / audio calls;
case 1: i call from computer to mobile phone and both are in same network, it works--
case 2: i call from mobile phone browser to computer and both are in same network, remote stream does not work--
case 3: i call from different network, remote stream does not work;--
i tried to change turn and stun servers but it did not work either;
The code;
function createPeer(userID: string, type: 'audio' | 'video') {
const peer = new RTCPeerConnection(configuration);
peer.ontrack = onTrackEvent;
peer.onicecandidate = onIceCandidateEvent(userID);
return peer;
}
function onTrackEvent(e: RTCTrackEvent) {
if (remoteStream.current) {
e.streams[0].getTracks().forEach((track) => {
remoteStream.current!.addTrack(track)
});
}
}
function onIceCandidateEvent (userID: string) {
return (e: RTCPeerConnectionIceEvent) => {
if (e.candidate) {
socket.emit('ice-candidate', {
userID,
candidate: e.candidate.candidate,
sdpMLineIndex: e.candidate.sdpMLineIndex,
sdpMid: e.candidate.sdpMid
})
}
}
}
function handlingAnswer({ sdp, myData, type }: { sdp: RTCSessionDescriptionInit, myData: any, type: 'audio' | 'video' } ) {
if (peerConnection.current) {
const desciption = new RTCSessionDescription(sdp);
peerConnection.current.setRemoteDescription(desciption)
.then(() => {
if (type === 'video') {
dispatch(callActions.gettingAnswerVideoCall(myData));
}
if (type === 'audio') {
dispatch(callActions.gettingAnswerVoiceCall(myData));
}
})
}
}
const makeCall = async (userID: string, type: 'audio' | 'video') => {
let constraints: MediaStreamConstraints = {};
if (type === 'video') {
constraints = {
video: true, audio: true
}
}
if (type === 'audio') {
constraints = {
audio: true
}
}
try {
const stream = await navigator.mediaDevices.getUserMedia(constraints);
localStream.current = stream;
remoteStream.current = new MediaStream();
peerConnection.current = createPeer(userID, type);
localStream.current.getTracks().forEach((track) => {
peerConnection.current!.addTrack(track, localStream.current!)
});
const sdp = await peerConnection.current!.createOffer();
await peerConnection.current!.setLocalDescription(sdp);
const payload = {
to: userID,
caller: {
_id: userData!._id,
name: userData!.name,
username: userData!.username,
picture: userData!.picture
},
sdp,
type
}
dispatch(callActions.callUser({
callType: type,
userID
}))
socket.emit('offer', payload)
} catch (error) {
console.log(error);
}
}
async function acceptCall(userID: string, sdp: RTCSessionDescriptionInit, type: 'video' | 'audio') {
let constraints: MediaStreamConstraints = {};
if (type === 'video') {
constraints = { video: true, audio: true }
}
if (type === 'audio') {
constraints = { audio: true }
}
try {
const stream = await navigator.mediaDevices.getUserMedia(constraints);
localStream.current = stream;
remoteStream.current = new MediaStream();
peerConnection.current = createPeer(userID, type);
localStream.current.getTracks().forEach((track) => {
peerConnection.current!.addTrack(track, localStream.current!)
})
const sessionDescription = new RTCSessionDescription(sdp);
await peerConnection.current.setRemoteDescription(sessionDescription);
const answer = await peerConnection.current.createAnswer();
await peerConnection.current.setLocalDescription(answer)
if (type === 'audio') {
dispatch(callActions.acceptVoiceCall())
}
if (type === 'video') {
dispatch(callActions.acceptVideoCall())
}
const payload = {
caller: userID,
sdp: answer,
myData: {
_id: userData!._id,
name: userData!.name,
username: userData!.username,
picture: userData!.picture
},
type
}
socket.emit('answer', payload)
} catch (error) {
alert(JSON.stringify(error))
}
}
socket.on('offer', handlingOffer);
socket.on('answer', handlingAnswer);
socket.on('ice-candidate', async ({ candidate, sdpMLineIndex, sdpMid }) => {
if (peerConnection.current) {
const rtcIceCandidate = new RTCIceCandidate({ candidate, sdpMLineIndex, sdpMid });
await peerConnection.current.addIceCandidate(rtcIceCandidate)
}
})
// In the Call Component
function CallComponent() {
useEffect(() => {
remoteVideoRef.current.srcObject = remoteStream.current
myVideoRef.current.srcObject = localStream.current
}, [])
return JSX .............................
}
Use this function to flatten the response returned from strapi on version 4. Helps you get rid of data and attributes properties
This will give you the same response structure as version 3 of strapi. This would help you migrate to version 4 from version 3 easily.
How to use it?
import the file.
const flattnedData = flattenObj({...data})
NOTE: The data here is the response returned from strapi version 4.
export const flattenObj = (data) => {
const isObject = (data) =>
Object.prototype.toString.call(data) === "[object Object]";
const isArray = (data) =>
Object.prototype.toString.call(data) === "[object Array]";
const flatten = (data) => {
if (!data.attributes) return data;
return {
id: data.id,
...data.attributes,
};
};
if (isArray(data)) {
return data.map((item) => flattenObj(item));
}
if (isObject(data)) {
if (isArray(data.data)) {
data = [...data.data];
} else if (isObject(data.data)) {
data = flatten({ ...data.data });
} else if (data.data === null) {
data = null;
} else {
data = flatten(data);
}
for (const key in data) {
data[key] = flattenObj(data[key]);
}
return data;
}
return data;
};
In my case I created a new middleware "flatten-response.js" in "middlewares" folder.
function flattenArray(obj) {
return obj.map(e => flatten(e));
}
function flattenData(obj) {
return flatten(obj.data);
}
function flattenAttrs(obj) {
let attrs = {};
for (var key in obj.attributes) {
attrs[key] = flatten(obj.attributes[key]);
}
return {
id: obj.id,
...attrs
};
}
function flatten(obj) {
if(Array.isArray(obj)) {
return flattenArray(obj);
}
if(obj && obj.data) {
return flattenData(obj);
}
if(obj && obj.attributes) {
return flattenAttrs(obj);
}
for (var k in obj) {
if(typeof obj[k] == "object") {
obj[k] = flatten(obj[k]);
}
}
return obj;
}
async function respond(ctx, next) {
await next();
if (!ctx.url.startsWith('/api')) {
return;
}
ctx.response.body = flatten(ctx.response.body.data)
}
module.exports = () => respond;
And I called it in "config/middlewares.js"
module.exports = [
/* ... Strapi middlewares */
'global::flatten-response' // <- your middleware,
'strapi::favicon',
'strapi::public',
];
I have an API which is returning uploaded file as blob. When I try to bind src with blob URL then it does not show anything, however, when I try to bind direct URL then it can show PDF file. Here is my code given below.
My TS code
downloadFile(fileData: Fileuploader) {
this.tempBlob= null;
//Fetching Data File
this.apiservice.getDownloadfile(fileData).subscribe(
(retFileData: any) => {
this.tempRetFileData = retFileData;
this.tempBlob = new Blob([retFileData], { type: this.contentType });
},
(err: Error) => {
},
() => {
const blob: Blob = new Blob([this.tempBlob], { type: this.contentType });
const fileName: string ='ilvsna.pdf';
this.myBlobURL = URL.createObjectURL(blob);
}
);
}
HTML
<pdf-viewer [src]="myBlobURL"
[render-text]="true"
[original-size]="false"
style="width: 400px; height: 500px"
></pdf-viewer>
Note: if I set myBlobURL URL to 'https://vadimdez.github.io/ng2-pdf-viewer/assets/pdf-test.pdf' then it can display
I think I have a solution for you. You can use ArrayBuffer. #N.F. Code is correct, however, you said that you got error in the line => this.pdfSrc = new Uint8Array(fileReader.result);
So, change the line into => this.pdfSrc = new Uint8Array(fileReader.result as ArrayBuffer);.Finally, your ts code should look like below=>
downloadFile(fileData: Fileuploader) {
this.tempBlob= null;
//Fetching Data File
this.apiservice.getDownloadfile(fileData).subscribe(
(retFileData: any) => {
this.tempRetFileData = retFileData;
this.tempBlob = new Blob([retFileData], { type: this.contentType });
const fileReader = new FileReader();
fileReader.onload = () => {
this.pdfSrc = new Uint8Array(fileReader.result as ArrayBuffer);
};
fileReader.readAsArrayBuffer(this.tempBlob);
},
(err: Error) => {
}
);
}
Try this.
ts
pdfSrc: Uint8Array;
downloadFile(fileData: Fileuploader) {
this.tempBlob= null;
//Fetching Data File
this.apiservice.getDownloadfile(fileData).subscribe(
(retFileData: any) => {
this.tempRetFileData = retFileData;
this.tempBlob = new Blob([retFileData], { type: this.contentType });
const fileReader = new FileReader();
fileReader.onload = () => {
this.pdfSrc = new Uint8Array(fileReader.result as ArrayBuffer);
};
fileReader.readAsArrayBuffer(this.tempBlob);
},
(err: Error) => {
}
);
}
html
<pdf-viewer [src]="pdfSrc"
[render-text]="true"
[original-size]="false"
style="width: 400px; height: 500px"
></pdf-viewer>
I resolve with window.URL.createObjectURL of my return blob file from service:
-- ts file
this.obuService.getObuDocument(obuId, fileId).subscribe(
(data: HttpResponse<Blob>) => {
const url = window.URL.createObjectURL(data.body);
this.src = url;
this.viewPDF = true;
}
);
-- service
getObuDocument(obuId: number, fileId: number): Observable<any> {
const options = {
observe: 'response' as 'body',
Accept: 'application/pdf',
responseType: 'blob' as 'blob'
};
return this.http.get(this.apiUrl + '/' + obuId + '/upload/' + fileId, options)
.pipe(catchError(err => { throw err; }));
}
export class AddCategory extends Component {
state = {
categoryForm: {
category: {
elementType: 'input',
elementConfig: {
type: 'text',
placeholder: 'Enter Category'
},
value: '',
validation: {
required: true
},
valid: false,
touched: false
}
}
};
checkValidity(value, rules) {
let isValid = true;
if (!rules) {
return true;
}
if (rules.required) {
isValid = value.trim() !== '' && isValid;
}
return isValid;
}
inputChangedHandeller = (event, controlNameOne) => {
const copyLoginFrom = {
...this.state.categoryForm,
};
const newCopy = {
...copyLoginFrom[controlNameOne]
};
newCopy.value = event.target.value;
newCopy.valid = this.checkValidity(newCopy.value, newCopy.validation);
newCopy.touched = true;
copyLoginFrom[controlNameOne] = newCopy;
let formIsValid = true;
for (let inputIdentifier in copyLoginFrom) {
formIsValid = copyLoginFrom[inputIdentifier].valid && formIsValid;
}
this.setState({
categoryForm: copyLoginFrom,
formIsValid: formIsValid
});
}
dataPost = (event) => {
event.preventDefault();
const formData = {};
for (let addressData in this.state.categoryForm) {
formData[addressData] = this.state.categoryForm[addressData].value;
}
const newAddress = {
newAddressData: formData
}
console.log("Hello......." + newAddress);
const parentId = this.state.parent_id;
const options = {
method: 'POST',
headers: {
Authorization: "Bearer " + localStorage.getItem("token")
},
data: formData,
url: 'http://localhost:8080/admin/category/'
}
axios(options);
}
render() {
const formElementsArray = []; //converting state object to the array I can loop throuh
for (let key in this.state.categoryForm) {
formElementsArray.push({
id: key,
config: this.state.categoryForm[key]
});
}
let form = ( <
form onSubmit = {
this.dataPost
} > {
formElementsArray.map(forElement => ( <
Input key = {
forElement.id
}
elementType = {
forElement.config.elementType
}
elementConfig = {
forElement.config.elementConfig
}
value = {
forElement.config.value
}
invalid = {
!forElement.config.valid
}
shouldValidate = {
forElement.config.validation
}
touched = {
forElement.config.touched
}
elementGet = {
(event) => this.inputChangedHandeller(event, forElement.id)
}
/>
))
}
<
button className = "btn btn-primary"
disabled = {
!this.state.formIsValid
} > Submit < /button> <
/form>
)
return ( <
div >
<
div className = {
styles.Login
} > {
form
} <
/div> <
/div>
)
}
}
I am trying to send data using axios but the output I am getting in mysql table is Null.Can anyone tell me what is the problem with my code.I tried printing the sent data on console and output I am getting is [object Object] I tried using stringify method but It gives error of header while posting data
try qs which is a query string parser:
npm install qs
and then :
import qs from "qs"
// in your body
const options = {
method: 'POST',
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
'Content-Type': 'application/x-www-form-urlencoded' // need to add content type
},
data: qs.stringify(formData),
url: 'http://localhost:8080/admin/category/'
}
I am new in angular. I want to store image data on local storage.
localStorage.setItem("imgData", JSON.stringify(this.files));
this saving data but no value.
how do I save please help
I have something similar to your issue, it could help you.
renderPNG(fileName: string) {
let reader = new FileReader();
reader.addEventListener("load", () = > {
this.files = reader.result;
localStorage.setItem('imgData', JSON.stringify(this.files));
}, false);
this.files = JSON.parse(localStorage.getItem('imgData'));
if (!this.files) {
this.downloadService.downloadFileSystem(fileName, 'png')
.subscribe(response = > {
if (response && response.body.size > 0) {
reader.readAsDataURL(response.body);
}
});
}
}
use fetch
fetch('http://cors-anywhere.herokuapp.com/https://lorempixel.com/640/480/?60789', {
headers: {},
}).then((response) => {
return response.blob();
}).then((blob) => {
console.log(blob);
}).catch((e) => console.log(e));
and save the blob with
https://www.npmjs.com/package/fs-web
await fs.writeFile(this.dirPath + '/' + fileName, blob);
read file and get url
await fs.readString(this.dirPath + '/' + fileName).then(async (blob: Blob) => {
if (!!blob) {
if (blob.type === 'text/html' || blob.type === 'application/octet-stream') {
await fs.removeFile(this.dirPath + '/' + fileName);
} else {
const url = window.URL.createObjectURL(blob);
}
}
}).catch((err) => {
throw (err);
});
Reference used in library for IonicFramework https://www.npmjs.com/package/ion-media-cache