Send image file and data in REACT JS to Codeigniter 3 with axios - reactjs

here is my front end code :
const api = axios.create({
baseURL: Backend_url+`Mode_ticketing_react/Ticketing/`
});
const Ticketing_rest = {
async post_nouveau_ticketing(
nouveau_ticket_fichier_joint,
email,
objet,
description,
categorie,
id_user
) {
try {
const result = await api.post(
"set_nouveau_ticketing/", {
email : email,
objet : objet,
description : description,
categorie : categorie,
id_user : id_user,
nouveau_ticket_fichier_joint : nouveau_ticket_fichier_joint
}
);
console.log("resultat envoye fichier ------", result)
return result.data;
}catch (error) {
console.log("erreur survenue" + error)
}
},
and take this services into view
function handleClick_soumettre_nouveau_ticket(e){
e.preventDefault();
setSpinner_button(true);
Ticketing_rest.post_nouveau_ticketing( champ_file_nouveau,
champ_email,
champ_objet,
champ_description,
champ_categorie,
flexi_auth.user_id
).then((result)=>{
//console.log(result)
});
}
all parameter is take from input field, and my problem is that ALL DATA is submited apart from the "champ_file_nouveau" field which is a file data.
function handleChange_champ_file_nouveau(e){
e.preventDefault();
setChamp_file_nouveau(e.target.files[0]);
console.log("selected file ------",e.target.files[0])
}
my backend is write in Codeigniter and I test it from Postman and it work!! so i think that the problem does not come from Backend but comes from FRONT END!
Any suggestions please.
I already try with FormData() class but does not work!

Related

SOLVED - How to open Streamable File as pdf in React client

I got this data from backend when try to get a pdf file:
`%PDF-1.7 %���� 5 0 obj <</Filter/FlateDecode/Length 823>>stream x���MS�0���{l���)&���#CCK'!%�ӿߕmb���;�y�Ҿ��K��H�����aN��q��%�Iz&#�i�T
<......>
1950
%EOF\`
How can REACT read and open this as pdf file in a new tab?
NOTE: I'm able to see the PDF file content in postman when call backend endpoint.
I tried this:
Backend controller (Nestjs):
#Get('/getPDF/:uuid')
async getFile(
#Param('uuid') uuid: string,
#Response({ passthrough: true }) res,
): Promise<StreamableFile> {
const resp = await this.service.downloadPDF(uuid);
if (!resp) {
return null;
}
res.header('Content-Type', `application/pdf`);
res.header('Content-Disposition', `attachment; filename="${resp.fileName}`);
return new StreamableFile(resp.buffer); // resp.buffer === Uint8Array
}
Frontend (REACT):
This will call backend api to get pdf file:
getPDF(uuid: string): Promise<AxiosResponse<Blob>> {
return this.httpClient.get(`${this.apiUrlPath}/getPDF/${uuid}`, {
responseType: 'blob',
});
}
This was supposed to render the pdf file
const response = await api.getPDF(uuid);
window.open(URL.createObjectURL(response.data));
I got this error:
TypeError: Failed to execute 'createObjectURL' on 'URL': Overload resolution failed.
UPDATED
Change AxiosResponse type from Blob to ArrayBuffer and create a new Blob from that buffer, solves the issue
This works:
getPDF(uuid: string): Promise<AxiosResponse<ArrayBuffer>> {
return this.httpClient.get(`${this.apiUrlPath}/getPDF/${uuid}`, {
responseType: 'arraybuffer',
});
}
const response = await api.getPDF(uuid);
const blob = new Blob([response.data], { type: "application/pdf" });
window.open(URL.createObjectURL(blob));
Thanks amir sarfar
Try passing a blob to createObjectURL:
const response = await api.getPDF(uuid);
const blob = new Blob([response.data], { type: "application/pdf" });
window.open(URL.createObjectURL(blob));

Property 'body' does not exist on type 'Observable<Object>'. Angular.js Discord OAuth2

Im making a Discord Bot Dashboard and implementing Discord OAuth2. I'm following the guide here: https://discordjs.guide/oauth2/#a-quick-example and the code is essentially the same.
async getJSONResponse(body) {
let fullBody = '';
for await(const data of body) {
fullBody += data.toString();
}
return JSON.parse(fullBody)
}
async getAccessToken(code) {
if (code) {
try {
let body = new URLSearchParams();
body.append('client_id', environment.discord.clientId)
body.append('client_secret', environment.discord.clientSecret)
body.append('code', code)
body.append('grant_type', 'authorization_code')
body.append('redirect_uri', environment.discord.redirect)
body.append('scope', 'identify')
let options = {
headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded')
};
const tokenResponseData = await this.http.post('https://discord.com/api/oauth2/token', body.toString(), options)
const oauthData = await this.getJSONResponse(tokenResponseData.body)
console.log(oauthData)
} catch(err) {
console.error('an error')
console.error(err)
}
}
}
However, I get this error: Property 'body' does not exist on type 'Observable<Object>'.
As you can see, the guide above clearly shows that body does in fact exist on the object.
I'm out of ideas, any help is appreciated.
Thanks

Trying to get SalesForce to recognize an Attachment as a PDF

I am able to use sObject to put an Attachment onto one of my records. The problem is that SF is not recognizing the file as a PDF but as a generic file.
const base64data = await new Buffer.from(pdfBuffer).toString('base64');
try {
await conn.sobject('Attachment').create({
ParentId: filename,
Name: resumeFileName,
Body: base64data,
ContentType: fileType,
Description: 'Resume Attachment',
});
} catch (e) {
console.log('Attachment Error', e);
}
When I look at the attachments of my record, the file does not have all of the options that a PDF file has (only download and delete)
Thanks in advance!
Turns out in order for Salesforce to recognize the pdf correctly you need to have the content type set to application/pdf AND the name of the file must include the .pdf extension. This worked for me:
(async () => {
const jsforce = require('jsforce');
const fs = require('fs');
var conn = new jsforce.Connection({
instanceUrl : '...',
accessToken : '...'
});
const pdfData = fs.readFileSync('./test.pdf').toString('base64');
try {
await conn.sobject('Attachment').create({
ParentId: '0012300000RWedX',
Name: 'My Test PDF.pdf', // <= Turns out the name has to have .pdf
Body: pdfData,
ContentType: 'application/pdf',
Description: 'Testing PDF Attachment',
});
} catch(err) {
console.error(err);
}
})();

AngularJS file upload, Express and node-postgres (pg)

Got a component in AngularJS (porting soon to Angular 7) for updating a user profile that invokes an AngularJS service method to perform a PUT to /api/user/:id.
Want to add a small photo (<100K) to send in the same PUT with the other fields then handle the request like this in the controller...
// route: PUT /api/user/:id
import db from '../../utils/db';
export async function upsert(req, res) {
const { id, name, phone, email, photo } = req.body;
// users.photo in PostgreSQL has datatype of bytea
const sql = `UPDATE users SET name = $2, phone = $3, email = $4, photo = $5) WHERE id = $1 RETURNING id, name, phone, email, photo;`;
const { rows } = db.query(sql, [id, name, phone, email, photo];
return res.status(200).send(rows);
}
Is there a clean way to encode the image client-side so it can be included in the JSON the AngularJS service PUTs? Other solutions I found seem like overkill for this use-case - requiring the image upload to be handled very differently from the other fields.
Ended up biting the bullet - creating a separate table for files along with its own API using formidable and node-postgres. In case this helps anyone else, here's how it turned out.
PostgreSQL data definition...
-- DROP SEQUENCE public.files_seq;
CREATE SEQUENCE IF NOT EXISTS public.files_seq;
-- DROP TABLE public.files;
CREATE TABLE IF NOT EXISTS public.files (
_id integer PRIMARY KEY DEFAULT nextval('files_seq'::regclass),
name character varying(512) NOT NULL,
type character varying(20) NOT NULL,
data bytea
);
-- DROP INDEX public.users_first_name;
CREATE INDEX files_name ON public.files USING btree (name);
Controller for Express...
import stream from 'stream';
import fs from 'fs';
import { IncomingForm } from 'formidable';
import db from '../../utils/db';
// Returns list of images
export async function index(req, res) {
const { rows } = await db.query('SELECT _id, name, type FROM files ORDER BY name;', []);
return res.send(rows);
}
// Uploads a single file
export async function upload(req, res) {
let _id;
new IncomingForm().parse(req, (err, fields, files) => {
if(err) throw err;
if(Array.isArray(files)) throw new Error('Only one file can be uploaded at a time');
const { name, type, path } = files.file;
fs.readFile(path, 'hex', async(err, fileData) => {
if(err) throw err;
fileData = `\\x${fileData}`;
const sql = 'INSERT INTO files (name, type, data) VALUES($1, $2, $3) RETURNING _id;';
const { rows } = await db.query(sql, [name, type, fileData]);
_id = rows[0]._id;
res.send({ id: _id });
// console.log(`Uploaded ${name} to ${path} and inserted into database (ID = ${_id})`);
// No need to delete the file uploaded as Heroku has an ephemeral file system
});
});
}
// Downloads a file by its _id
export async function download(req, res) {
const _id = req.params.id;
const sql = 'SELECT _id, name, type, data FROM files WHERE _id = $1;';
const { rows } = await db.query(sql, [_id]);
const file = rows[0];
const fileContents = Buffer.from(file.data, 'base64');
const readStream = new stream.PassThrough();
readStream.end(fileContents);
res.set('Content-disposition', `attachment; filename=${file.name}`);
res.set('Content-Type', file.type);
readStream.pipe(res);
return rows[0];
}
// Deletes a file from the database (admin-only)
export async function destroy(req, res) {
const _id = req.params.id;
const sql = 'DELETE FROM files WHERE _id = $1;';
await db.query(sql, [_id]);
res.status(204).send({ message: `File ${_id} deleted.`});
}
On the client side, I'm using ng-file-upload with AngularJS.
Here's the relevant part of the view (in pug for brevity)...
.form-group.col-md-6
label(for='photo') Teacher photo
input.form-control(ngf-select='$ctrl.uploadPhoto($file)', type='file', id='photo', name='photo', ng-model='$ctrl.user.photo', ngf-pattern="'image/*'", ngf-accept="'image/*'", ngf-max-size='100KB', ngf-min-height='276', ngf-max-height='276', ngf-min-width='236', ngf-max-width='236', ngf-resize='{width: 236, height: 276}', ngf-model-invalid='errorFile')
ng-messages.help-block.has-error(for='form.photo.$error', ng-show='form.photo.$dirty || form.$submitted', role='alert')
ng-message(when='maxSize') Please select a photo that is less than 100K.
ng-message(when='minHeight,maxHeight,minWidth,maxWidth') The image must be 236 x 276 pixels.
span(ng-if='$ctrl.user.imageId')
img(ng-src='/api/file/{{ $ctrl.user.imageId }}' alt="Photo of Teacher")
and method in its controller...
uploadPhoto(file) {
if(file) {
this.uploadService.upload({
url: '/api/file/upload',
data: { file }
})
.then(response => {
this.user.imageId = response.data.id;
}, response => {
if(response.status > 0) console.log(`${response.status}: ${response.data}`);
}, evt => {
// Math.min is to fix IE which reports 200% sometimes
this.uploadProgress = Math.min(100, parseInt(100.0 * evt.loaded / evt.total, 10));
});
}
}

ionic 3 acces to json key

i can't access to a key of a json response from a restful web service.
{"_body":"{\"values\": {\"user_id\":\"1\",\"name\":\"fred test\",\"email\":\"fred#test.test\",\"username\":\"fredtest\",\"token\":\"d5f66a06ec809d70d0c52842df8dc0011d7d1ad0f2d56f50d3123da17a2489fe\"}}","status":200,"ok":true,"statusText":"OK","headers":{"pragma":["no-cache"],"content-type":["text/html;charset=UTF-8"],"cache-control":["no-store"," no-cache"," must-revalidate"],"expires":["Thu"," 19 Nov 1981 08:52:00 GMT"]},"type":2,"url":"http://localhost/PHP-Slim-Restful/api/login"}
I would like to acces to 'values' in this function: (this.responseData.values)
login(){
console.log('login'+ this.userData);
// Your app login API web service call triggers
this.authService.postData(this.userData,'login').then((result) => {
this.responseData = result;
console.log('userdata : '+ temp);
if(this.responseData.values){
console.log('response: ' + this.responseData);
localStorage.setItem('userData', JSON.stringify(this.responseData));
this.navCtrl.push(TabsPage);
}
else{
this.showToastWithCloseButton()
}
}, (err) => {
console.log('erreur : '+err);
});
}
I have an error undifined!
Can you help me?
I have used Observable to return json data and using the subscribe function in my method and using response.json() to convert the JSON reponse from RESTful webservices.
My component method,
import {Http, Headers, Response, RequestOptions} from '#angular/http';
import {Observable} from 'rxjs/Rx';
var response = this.service.post('deleteUserDetails/'+this.selectedUserId, null);
response.subscribe((res) => {
var response = res.json();
});
Service Post method,
post(url: string, data : any): Observable<any> {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
let options = new RequestOptions({ headers: headers});
return this.http.post(url, data,{headers: headers});
}
I think this might be helpful for your query.
You can make a for in your JSON and access the return values of your post. Something like that.
"this.responseData = result.json();" -> Return JSON. Make a for.
Example:
public postData(data, url: string) {
this.http.post(url, data).toPromise().then(res => {
let responseData = res.json();
if (responseData) {
for (var item of responseData) {
//Implments
}
}
}, (err) => {
});
}

Resources