I'am trying to upload a file to the server by using a service which passes the file to the php backend.
It works, but only once. If I try to repeat uploading another file (without reloading the page) it does not get send and this error occurs:
ERROR TypeError: "this.fileManagerService.uploadFile is not a function"
playground.component.html
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<input type="file" name="avatar" (change)="onFileSelect($event)" />
<button type="submit">Upload</button>
</form>
playground.component.ts
export class PlaygroundComponent implements OnInit {
form: FormGroup;
fileManagerResponse;
constructor(private formBuilder: FormBuilder, private fileManagerService: FileManagerService) { }
ngOnInit() {
this.form = this.formBuilder.group({
avatar: ['']
});
}
onFileSelect(event) {
if (event.target.files.length > 0) {
const file = event.target.files[0];
this.form.get('avatar').setValue(file);
}
}
onSubmit() {
const formData = new FormData();
formData.append('avatar', this.form.get('avatar').value);
this.fileManagerService.uploadFile(formData).subscribe(
(res) => {
this.fileManagerService = res;
console.log(res);
},
(err) => {
console.log(err);
}
);
}
}
FileManagerService.ts
export class FileManagerService {
SERVER_URL: string = "http://127.0.0.1/backend/api/";
constructor(private httpClient: HttpClient) { }
public uploadFile(data) {
let uploadURL = `${this.SERVER_URL}/filemanager/upload.php`;
return this.httpClient.post<any>(uploadURL, data);
}
}
The error occurred in below line.
this.fileManagerService = res;
You cannot assign res to the instance of the FileManagerService.
Remove it. Everything will be fine.
Related
i use Laravel-filepond and Vue FilePond.
but FilePond send a blank request to server.
this is my codes:
*UserComponent.vue
<template>
<div class="container">
<file-pond
name="Profile"
ref="pond"
label-idle="drag & drop"
v-bind:allow-multiple="false"
accepted-file-types="image/jpeg, image/png"
v-bind:files="userFile"
v-bind:server="{
url: '/panel/filepond',
timeout: 7000,
process: {
url: '/process',
method: 'POST',
headers: {
'X-CSRF-TOKEN': this.get_meta('csrf-token'),
},
}
}"
v-on:init="handleFilePondInit"/>
</div>
</template>
<script>
import vueFilePond, {setOptions} from 'vue-filepond';
import 'filepond/dist/filepond.min.css';
import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css';
import FilePondPluginFileValidateType from 'filepond-plugin-file-validate-type';
import FilePondPluginImagePreview from 'filepond-plugin-image-preview';
import FilePondPluginImageEdit from 'filepond-plugin-image-edit';
const FilePond = vueFilePond(FilePondPluginFileValidateType, FilePondPluginImagePreview);
export default {
data() {
return {
userFile: [],
}
},
methods: {
handleFilePondInit: function () {
console.log('FilePond has initialized');
}
},
components: {
FilePond
},
}
</script>
FilePondController.php Original file
<?php
namespace Sopamo\LaravelFilepond\Http\Controllers;
use function dd;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller as BaseController;
use Sopamo\LaravelFilepond\Filepond;
class FilepondController extends BaseController
{
private $filepond;
public function __construct(Filepond $filepond)
{
$this->filepond = $filepond;
}
public function upload(Request $request)
{
dd($request->all());
}
}
when I upload a file on client side (in default response with 422), I can not find it on my server.
FrameWorks & Repository is on last version.
Response
[]
According to the author, you are sending the metadata instead of the file itself. I solved this using the advanced custom process function that you can found in documentation. There you can find the comments about what almost every part of the code does.
data() {
return {
server: {
url: 'http://base-url.test',
process: (fieldName, file, metadata, load, error, progress, abort, transfer, options) => {
const formData = new FormData();
formData.append(fieldName, file, file.name);
const request = new XMLHttpRequest();
request.open('POST', 'url-to-post-to');
request.setRequestHeader('X-CSRF-TOKEN', 'your-csrf-token');
request.upload.onprogress = (e) => {
progress(e.lengthComputable, e.loaded, e.total);
};
request.onload = function () {
if (request.status >= 200 && request.status < 300) {
load(request.responseText);
} else {
error('Error');
}
};
request.send(formData);
return {
abort: () => {
request.abort();
abort();
},
};
},
},
}
},
Then you only need to bind it:
<template>
<div class="container">
<file-pond
name="Profile"
ref="pond"
label-idle="drag & drop"
v-bind:allow-multiple="false"
accepted-file-types="image/jpeg, image/png"
v-bind:files="userFile"
v-bind:server="server"
v-on:init="handleFilePondInit" />
</div>
</template>
responseText is the unique Id from the server. Maybe you want to emit it to parent component:
data() {
return {
server: {
url: 'http://base-url.test',
process: (fieldName, file, metadata, load, error, progress, abort, transfer, options) => {
const thisReference = this;
// Other code
request.onload = function () {
if (request.status >= 200 && request.status < 300) {
thisReference.
thisReference.$emit('my-event', request.responseText);
load(request.responseText);
} else {
error('Error');
}
};
// Other code
},
},
}
},
Pretty similar if you want to know what file has been reverted (in this case, you need to response from server with the same id you sent):
data() {
return {
server: {
// Process, url, etc.
revert: {
url: '/url-to-delete',
method: 'DELETE',
headers: {
'X-CSRF-TOKEN': 'your-csrf-token'
},
onload: (idDeleted) => this.$emit('my-event', idDeleted)
},
},
}
},
When I try to upload a file on my Symfony API, I have an error from MediaObjectAction.php which is a controller.
This file looks like this :
final class CreateMediaObjectAction extends AbstractController
{
public function __invoke(Request $request): MediaObject
{
$uploadedFile = $request->files->get('file');
if (!$uploadedFile) {
throw new BadRequestHttpException('"file" is required');
}
$mediaObject = new MediaObject();
$mediaObject->file = $uploadedFile;
return $mediaObject;
}
}
and it throws me the error : "file" is required
In the front-end, I use ReactJS and I do a simple file upload with these functions :
const handleFileChange = (event) => {
console.log(event.target.files[0])
setFile({ selectedFile: event.target.files[0], loaded: 0 })
}
const uploadFile = () => {
FileUtils.uploadFile(MEDIA_OBJECT_ENDPOINT, file.selectedFile)
.then((response) => {
console.log(response)
})
const FileUtils = {
uploadFile: async (url, file) => {
const data = new FormData()
data.append('name', 'file')
data.append('file', file)
const response = await api.post(url, data)
return response
},
}
And in html, the file input looks like this :
<input
type="file"
id="file"
name="file"
onChange={handleFileChange}
></input>
As you can see, it is very basic, but it does not work and I cannot figure out why. Do you have an idea of what I miss ?
PS : The function api.post() works very well, the problem does not come from it.
In php, I cannot access the uploaded files in $_FILES instead they appear in $_POST["imgs"] as [object File] without any properties like name.
How can I get those files accessed in $_FILES?
import React, { useCallback } from 'react'
import { useDropzone } from 'react-dropzone'
import axios from 'axios'
const imgAjaxUploader = axios.create({
baseURL: 'http://localhost',
timeout: 1000,
headers: { 'Content-Type': 'mulipart/form-data' }
});
export default function ImgDropzone() {
const onDrop = useCallback(acceptedFiles => {
const formData = new FormData()
formData.append('imgs', acceptedFiles)
try {
imgAjaxUploader.post('/store/admin/imgHandler.php', formData, {
headers: {
'Content-Type': 'mulipart/form-data'
}
}).then(data =>
console.log(data)
).catch(err => {
console.log(err)
return null
})
} catch (err) {
alert(err)
}
}, [])
const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop: onDrop, accept: 'image/jpeg, image/png' })
return (
<div {...getRootProps()} style={{ display: "inline-block" }}>
<input {...getInputProps()} />
{
isDragActive ?
<p>Drop the files here ...</p> :
<p>Drag 'n' drop some files here, or click to select files</p>
}
</div>
)
}
I found the solution. Multiple files need to be appended to the same name with a trailing [], in order to be compatible with PHP:
acceptedFiles.forEach(file => {
formData.append('imgs[]', file)
})
resource example 3
I have a problem with my ionic app.
I want to upload an image to my php server when i click on a button but it seems that i am doing something wrong...
Communication.html
<ion-header>
<ion-navbar>
<ion-title>
Ionic3 Server Send Test
</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-list>
<ion-item>
<button ion-button (click)="uploadFile()">Upload</button>
</ion-item>
</ion-list>
</ion-content>
Communication.ts
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { HttpClient } from '#angular/common/http';
import { FileTransfer, FileUploadOptions, FileTransferObject } from '#ionic-native/file-transfer';
#Component({
selector: 'communication',
templateUrl: 'communication.html'
})
export class CommunicationPage {
imageURI:any;
imageFileName:any;
constructor(public navCtrl: NavController,
private transfer: FileTransfer) {}
uploadFile() {
const fileTransfer: FileTransferObject = this.transfer.create();
let options: FileUploadOptions = {
fileKey: 'ionicfile',
fileName: 'ionicfile',
chunkedMode: false,
headers: {}
}
fileTransfer.upload('C:/Users/Nathan/Desktop/Recognize/src/pages/communication/test.png', 'http://someserver', options)
.then((data) => {
console.log(data+" Uploaded Successfully");
}, (err) => {
console.log(err);
});
}
}
I have this error when i click on the upload button :
FileTransferError {code: 1, source:"C:/Users/Nathan/Desktop/Recognize/src/pages/communication/test.png", target: "http://someserver", http_status: null, body: null, …}
I know there is a problem with the url of the "test.png" file because of code 1 error.
Do you have any idea ?
You need to add image targetPath in fileTransfer.upload() like this,
var targetPath = this.file.dataDirectory + imgName;
fileTransfer.upload(targetPath, 'http://someserver', options)
.then((data) => {
console.log(data+" Uploaded Successfully");
}, (err) => {
console.log(err);
});
Hey Nathan the problem you are having is because of the URL of file, here you are giving the url only test.png.
Rather than you should use FileChooser plugin for cordova which gives the absolute URL of the file.
import { FileChooser } from '#ionic-native/file-chooser';
constructor(private fileChooser: FileChooser) { }
function() {
const fileTransfer: FileTransferObject = this.transfer.create();
let options: FileUploadOptions = {
fileKey: 'ionicfile',
fileName: 'ionicfile',
chunkedMode: false,
headers: {}
}
this.fileChooser.open()
.then(uri => {
fileTransfer.upload(uri, 'http://someserver', options)
.then((data) => {
console.log(data+" Uploaded Successfully");
}, (err) => {
console.log(err);
});
})
.catch(e => console.log(e));
}
Comment down if you want some more help.
I am trying to upload file to read in php. But, I unable to transmit a file over to the php.
My code was,
HTML Code:
<label>Import</label>
<div class="form-group">
<input type="file" ng-file-select="uploadFile($files)" />
</div>
app.js:
var app = angular.module('myApp','ngRoute','myApp.bulk','ngSanitize','angularFileUpload']);
bulk.js
var bulkApp = angular.module('myApp.bulk', ['ngResource','ngRoute','ngSanitize']);
bulkApp.factory('FileUploadService', function ($http) {
var api = {
uploadFile: function (file, callback) {
alert(file.name);
$http.uploadFile({
url: 'xxx/services.php?upload=1',
file: file
}).progress(function(event) {
console.log('percent: ' + parseInt(100.0 * event.loaded / event.total));
}).error(function (data, status, headers, config) {
console.error('Error uploading file')
callback(status);
}).then(function(data, status, headers, config) {
callback(null);
});
}
}
return api;
});
bulkApp.controller('bulkController', function($scope,$rootScope,$filter,FileUploadService) {
var service = FileUploadService;
/**
* Handler to upload a new file to the server.
*/
$scope.uploadFile = function ($files) {
var $file = $files[0];
service.uploadFile($file, function (error) {
if (error) {
alert('There was a problem uploading the file.');
}
// handle successfully-uploaded file
})
}
});
services.php
if(isset($_REQUEST) && isset($_REQUEST['upload']))
{
var_dump($_FILES);
/* read functionality over here */
}
I referred this link
i am getting TypeError: $http.uploadFile is not a function error.
please help. thanks in advance .
use $upload service instead of $http:
bulkApp.factory('FileUploadService', function ($upload) {
var api = {
uploadFile: function (file, callback) {
$upload.upload({
url: 'xxx/services.php?upload=1',
file: file
}).progress(function(event) {
console.log('percent: ' + parseInt(100.0 * event.loaded / event.total));
}).error(function (data, status, headers, config) {
console.error('Error uploading file')
callback(status);
}).then(function(data, status, headers, config) {
callback(null);
});
}
}
return api;
});