retrieving multiparts/ form data from angular to laravel php RESTfull api - php

I have an app developed using ionic angular and I want to upload files and send to laravel php
here I what I have done but this not working.
Here is my submit form in ionic angular :
async submitForm(){
let options = {headers: new HttpHeaders({
'Content-Type': 'multi-part/formdata',
}) };
let formData= new FormData();
formData.append("photo",this.file, this.file.name);
// console.log(formData)
this.http.post<any>(this.env.API_URL + 'auth/form', formData, options).subscribe(
data => {
this.alertService.presentToast("تم رفع الملفات بنجاح");
},
error => {
console.log(error);
},
)
laravel side:
public function apistore(Request $request)
{
$user = Auth::user()->id;
$this->validate($request, [
// 'photo' => 'required',
]);
$image = $request->{'photo'};
if($image->hasFile('photo'))
{
$file=$image->file('photo');
$filename = $file->getClientOriginalName();
$extension = $file->getClientOriginalExtension();
$picture = date('His').'-'.$filename;
$file->move(public_path().'/attach/images', $picture);
}
$attachments= new attachments();
$attachments->filename=$image;
$attachments->user_id = Auth::user()->id;
$attachments->take_image = $request->{'take_image'};
$attachments->save();
return response()->json([
'success' => true,
'data' => $attachments->toArray(),
'message' => 'Data updated'
]);
}
I usually retrieve data from ionic like this and it is working
$job_info->job = $request->{'job_info.job'};

Related

How to store file in laravel PHP

Language used : js with react - redux-toolkit and php with laravel
I'm trying to save my file in my mongodb database
first of all, here my input file and axios function to post from client (react) to server(laravel) . (it's working, i received the data in php)
import React from 'react';
export const Attach = ({ register, setValue }) => {
const handleFile = (e) => {
setValue('Attachment', e.target.files[0]);
};
return (
<div >
<label >Insert a file </label>
<input type="file" name="file" onChange={(e) => handleFile(e)} />
</div>
);
};
and my axios post function
export const postOffers = (data) => (dispatch) => {
axios({
method: 'post',
url: `${process.env.REACT_APP_API_URL}offer`,
data: {
Type: Type,
UserName: data.UserName,
Object: data.Object,
Address: data.Address,
Comment: data.Comment,
Attachment: data.Attachment,
},
}).then((res) => {
if (!res.data) {
console.log('error form');
} else {
console.log(data.Attachment);
}
});
};
-> console.log(data.Attachment);
then in my php controller :
public function createOffers(Request $request)
{
if ($request) {
//what i have tried
//upload file
$bucket = InternOffer::getMongoDB()->selectGridFSBucket();
$file = $request->file('Attachment');
$resource = fopen($file, "a+");
$file_id = $bucket->uploadFromStream($file, $resource);
$InternOffer = InternOffer::create([
'Type' => $request->get('Type'),
"UserName" => $request->get('UserName'),
'Object' => $request->get('Object'),
'Address' => $request->get('Address'),
'Comment' => $request->get('Comment'),
// 'Attachment' => $file_id, (working if i don't pass the attachment)
]);
if ($InternOffer) {
$InternOffer->save();
return ["result" => "Offers has been successfully created"];
} else {
return ["result" => "failed"];
}
}
}

when sent data via Ajax to a Controller in Laravel the data is null

I have used Ajax to sent data to the controller, unfortunately when I retrieve data it's empty nothing is sent. although it does give me the data when I get it via JQuery before it's sent.
below is the code of Ajax -------------------
$.ajax({
url: $('form#add-user-form').attr('action'),
method: $('form#add-user-form').attr('method'),
data: form.serializeArray(),
processData: false,
dataType: 'json',
contentType: false,
beforeSend:function(){
$(form).find('span.error-text').text('');
alert('working' + " " + user['fname']);
},
success:function(data){
if (data.code == 0 ){
$.each (data.error, function(prefix, value){
alert(prefix + ' ' + value[0]);
$(form).find('span.'+prefix+'_error').text(value[0]);
});
alert('complete');
}else {
$(form)[0].reset();
alert(data.msg)
}
}
});
-----------------Laravel Controller method which receives the data ----------------
public function store(Request $request)
{
$validator = \Validator::make($request -> all(), ['fname' => 'required|min:5|max:25',
'lname' => 'required|min:5|max:25',
'email' => 'required|email|unique:users',
'pass' => 'required|min:8|max:20|',
'confirm-pass' => 'required|min:8|max:20'
]);
if (!$validator -> passes() ){
return response()->json(['code'=> 0, 'error'=> $validator->errors()->toArray(), $request->fname]);
}else {
$user = new users();
$user -> name = $request -> fname ;
$user -> email = $request -> email ;
$user -> password = $request -> pass;
$query = $user -> save();
if ( !$query ){
return response() -> json(['code'=> 0, 'msg' => 'something went wrong']);
}else {
return response() -> json(['code' => 1, 'msg' => 'users has been successfully added']);
}
}
}
I have found the answer, instead of using $.ajax method, I replaced it with $.post function of JQuery and everything is working perfect.

Laravel Vue Dropzone.js request file return NULL

I have a problem, and I can't fix it. I read a lots of forum and issues, but it don't resolve.
The problem is that
$photos = $request->file('file');
return var_dump($photos);
bring NULL. I tried to find the error, but I can't
I want store images on server and in a table, then it connecting to an another products table,
First write in the inputs some data ex. Name,Category, after an other tab upload the images with Dropzone, and save it in one time together.
I am use rowanwins dropzone.
My ... .blade.php
<form method="POST" enctype="multipart/form-data" action="{{ route('product.createnew') }}">
// Other Products inputs ..
//Uploads
<vue-dropzone
ref="myVueDropzone"
id="dropzone"
:options="dropzoneOptions">
</vue-dropzone>
// / form and scripts section
<script>
var url = "{{ route('product.createnew') }}";
console.log(url);
var app = new Vue({
el: '#app',
data: function () {
return {
dropzoneOptions: {
url: url,
thumbnailWidth: 150,
maxFilesize: 2,
maxFiles: 2,
acceptedFiles: ".jpeg,.jpg,.png,.gif",
autoDiscover : true,
clickable : true,
uploadMultiple :true,
addRemoveLinks:true,
headers: {
"X-CSRF-TOKEN": document.head.querySelector("[name=csrf-token]").content
},
},
radioButton: '0',
}
},
methods: {
deleteDropFile(index) {
this.dropFiles.splice(index, 1)
},
}
});
My Create Controller
public function create(Request $request)
{
$validator = Validator::make($request->all(), [
//Other products input
'file' => 'nullable|mimes:jpeg,jpg,png,gif|max:2048',
]);
//$products = new Products
//$products->save();
$photos = $request->file('file');
return var_dump($photos);
if (!is_array($photos)) {
$photos = [$photos];
}
for ($i = 0; $i < count($photos); $i++) {
$photo = $photos[$i];
$savename = sha1(time() . '.' . $request->get('name'))."_$i";
$images = new ProductImages ([
'name' => $request->get('name'),
'post_id'=> $products->id,
'path'=> public_path('uploads') . '/' . $savename,
'main'=> 0,
]);
$images->save();
Image::make($photo)
->resize(250, null, function ($constraints) {
$constraints->aspectRatio();
})
->save(public_path('uploads'). '/' . $savename);
$photo->move(public_path('uploads'), $savename);
}
return redirect()->back();
}
My routes
Route::group(['prefix' => 'product'], function () {
Route::get('/create', 'ProductController#index')->name('product.create'); //View
Route::post('/createnew', 'ProductController#create')->name('product.createnew'); //Post
});
After all I found what is wrong.
It is the validation
'file' => 'nullable|mimes:jpeg,jpg,png,gif|max:2048',
throw the error.
Thanks

How to save data using ajax request in Laravel version 5.5

My ajax call:
$('#password_change_form').submit(function(e) {
e.preventDefault();
var saveThis = this;
$.ajax({
type: "POST",
url: "{{ url('/changepassword') }}",
data: $(saveThis).serialize(),
success: function(data) {
$("#password_change_form").trigger("reset");
alert(data);
}
});
}),
My Controller method:
public function changepassword(Request $request){
$user = Auth::guard()->user();
$request_data = $request->All();
$validator = $this->admin_credential_rules($request_data);
if($validator->fails()) {
$errors = $validator->errors();
$errors = json_decode($errors);
return response()->json([
'success' => false,
'message' => $errors
], 422);
} else {
$current_password = $user->password;
if(md5($request_data['password']) == $current_password) {
$user_id = $user->id;
$obj_user = User::find($user_id);
$obj_user->password = md5($request_data['new_password']);
$obj_user->save();
$msg = "password has been changed";
return response()->json(array('change_password'=> $msg), 200);
} else {
$error = array('error' => array('Heslo, které jste zadali, je neplatné.'));
return response()->json([
'modal_message_danger' , "Heslo, které jste zadali, je neplatné.",
'message' => $error
], 422);
}
}
}
When I hit the submit button on the popup form it shows me the HTML alert. I have also attached the screen shot of this alert:
Here my data is not saving. I am kind of confused about this problem. Please help me regarding this problem.
Your help will be highly appreciated!
Here is a screenshot of my alert:
The question is if your javascript in within your blade.php file if it's not in your blade.php you can't use the blade syntax:
url: "{{ url('/changepassword') }}",
the bracers or only valid within the blade template area not in your js just replace it with this
url: "/changepassword",
Further add check if you get any data from your javascript like this in your controller method
dd($request->all());
If it does output your the data you are trying to sent your ajax works if not it does not.

VueJs Laravel Image Upload

Like the title says, I'm trying to do an image upload from VueJs to a Laravel endpoint. I discovered that the only way(if there is another please tell me) is to send the base64 of the image through the request. On the Vue side I think everything is covered.
However, on the Laravel side is where it gets complicated. I can't decode the base64 string that gets passed, and when I try to store the image in my AWS S3 bucket, it doesn't store properly. Here is the code:
VueJS
<template>
<input type="file" name="image" class="form-control" #change="imagePreview($event)">
</template>
methods: {
submitForm(){
axios.defaults.headers.post['Content-Type'] = 'multipart/form-data';
axios.post(this.$apiUrl + '/article', {
image: this.image
}).then(response => {
flash(response.data.message, 'success');
}).catch(e => {
console.log(e);
})
},
imagePreview(event) {
let input = event.target;
if (input.files && input.files[0]) {
var reader = new FileReader();
let vm = this;
reader.onload = e => {
this.previewImageUrl = e.target.result;
vm.image = e.target.result;
}
reader.readAsDataURL(input.files[0]);
}
}
}
Laravel:
$this->validate($request, [
'image' => 'required',
]);
// return response()->json(base64_decode($request->image));
$timestampName = microtime(true) . '.jpg';
$url = env('AWS_URL') . '/article_images/' .$timestampName;
Storage::disk('s3')->put($timestampName, base64_decode($request->image));
If I add the image validation rule, it says it's not an image..
I would also like to retrieve the extension if possible.
you can do it using FormData in JS part and use getClientOriginalExtension() on the file to get the extension in Laravel.
VueJS
imagePreview(event) {
let selectedFile = event.target.files[0];
vm.image = selectedFile;
}
submitForm(){
let fomrData = new FormData();
formData.append('image', vm.image);
axios.post(this.$apiUrl + '/article', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then(response => {
flash(response.data.message, 'success');
})
.catch(e => {
console.log(e);
});
}
Laravel
$this->validate($request, [
'image' => 'required',
]);
$image = $request->file('image');
$extension = $image->getClientOriginalExtension(); // Get the extension
$timestampName = microtime(true) . '.' . $extension;
$url = env('AWS_URL') . '/article_images/' .$timestampName;
Storage::disk('s3')->put($url, file_get_contents($image));
Here is a link that might be useful
Hope that it helps.

Categories