How can I get the signature image from this signature pad with Vuejs + Laravel - laravel

Hi I have this signtaure pad with Vuejs:
Signature pad code
I am trying to send this data into a controller to store it, but when I do this:
const { isEmpty, data } = this.$refs.signaturePad.saveSignature();
console.log(isEmpty);
console.log(data);
let formData = new FormData();
formData.append('signtaure', this.$refs.signaturePad.saveSignature());
axios.post('/api/employee/update/27141399-8?api_token='+App.apiToken, formData, config)
.then(function (response) {
currentObj.success = response.data.success;
})
If I check the console.log() it displays this:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABioAAAJxCAYAAADcoOoFAAAAAXNSR0IArs4c6QAAIABJREFUeF7s3c+LrUmaF/AYN25GqkXGndbIbEQYSxQUV+WAi9lIzT8g1S5ddbkQXAhVsxSErlq7qGpcupgqcCHCYNfGhQhjLcQfMM604CC6GAsFR8Fp+eL7jNGnT96b92bmiXif83khOXnvPXki4vNEZla93xMRPzNcBAgQIECAAAECBAgQIECAAAECBAgQIECAAIFFAj+zqF3NEiBAgAABAgQIECBAgAABAgQIECBAgAABAgSGoMIkIECAAAECBAgQIECAAAECBAgQIECAAAECBJYJCCqW0WuYAAECBAgQIECAAAECBAgQIECAAAECBAgQEFSYAwQIECBAgAABAgQIECBAgAABAgQIECBAgMAyAUHFMnoNEyBAgAABAgQIECBAgAABAgQIECBAgAABAoIKc4AAAQIECBAgQIA
I check the laravel controller to get the file like this:
$request->signature;
And it is empty.. a blank value so I wonder how can I send the base_64 image with vuejs to the controller because how I am doing it does not work

You append the signature to the formdata object like this:
formData.append('signtaure', this.$refs.signaturePad.saveSignature());
In the laravel controller you're checking for the signature property on the request object.
Notice the typo you've made within the append function? signtaure != signature.
#julianstark999 also made a comment about this, but I think you misinterpreted his comment, so I'm explaining it again :)

Related

Cannot send HTML string through axios

I'm working on a blog like website and have being adding this rich text editor feature to it. This app is built with Vue for the front and Laravel, and this text editor is a dependency called vue-quill.
I use axios to post all the data and nothing more. Im using it to create posts with Raw html tags from this editor, it actually works fine creating and updating posts locally, but only fails on my server whenever you try to update any post, it returns empty response and status 200.
It does not happen when you create a post. Im not using any kind of image upload service but I'm using my own solution, which consists on transforming images from base 64 to file objects and then send them to a controller via axios. On update action it is similar but the images that were already uploaded on the post are fetched, then converted to base64 again and then converted to file objects again (in order to preserve previous images) for new images I convert them from base64 to file object as I do on my create action.
Here is the code I use to create from base 64 to file object :
dataURLtoFile(dataurl, filename) {
let arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, {type:mime});
}
And this would be my axios action:
axios
.post("/api/posts", formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then((response)=>{
this.submit = false;
this.title= '';
this.showAlert("success", 'Post created successfully.' , '')
})
.catch((error) =>{
// etc
});
The formData object only store the raw html, images and a string, nothing more than that, but I'm not sure if the headers of the axios are ok, the laravel action is like this:
public function updatePost(Request $request)
{
$request->validate([
'files.*' => 'required|mimes:jpg,jpeg,png|max:2048'
]);
$post = Post::find($request->postId);
$images = $request->file('files');
// creamos el post primero
$post->title = $request->title;
$post->body = $request->body;
$post->save();
// the rest of the code for storing images
return response()->json(['post' => $post]);
I think something is preventing it to reach to this action, because the response is empty.
Edit: I had a problem later where the request was giving status 301, after searching here and there I found out that everything was okay but in the server. The host has to be configured as stated here in this quick guide for 301 troubles : https://medium.com/#mshanak/laravel-return-empty-response-690f8a308d9a.

Issue with Integers passing data from Vue to Laravel using FormData

I am successfully updating a database using Vue 2 to a Laravel 8 Controller using Axios. However, I am stuck when attempting to pass an integer to my database.
My database has a column, 'number_of_searches' and it must be an integer.
Laravel Migration looks like this:
$table->integer('number_of_searches')->nullable();
And the model looks something like this:
class Product extends Model
{
protected $fillable = [
'product_title',
'number_of_searches' => 'integer',
];
}
My Vue updateProduct() function used FormData and appends the values coming from the form. It looks like this:
updateProduct(product){
let data = new FormData();
data.append('_method', 'PATCH');
data.append('product_title', product.product_title);
data.append('number_of_searches', product.number_of_searches);
axios.post('/api-route-to-update/product_id/', data)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
My update controller looks like this:
public function update(Request $request, $product_id){
$product = Product::findOrFail($product_id);
$product->update($request->all());
$product->save();
}
I can have as many input fields as I need and it works perfectly as long as they are strings. However, when I use a number input field in my component such as:
<input v-model="product.number_of_searches" type="number" min="1" max="999">
The generated json that will pass from axios into my controller looks like this:
{ "id": 5, "product_title": "The Product Title will work great", "number_of_searches": "222"}
You will notice that 'number_of_searches' is passed as a string, hence my database fails because it is the wrong datatype, it requires an integer. After reading the documentation and other threads, it seems that FormData will always return strings and that I must just deal with this on the server side.
So what I did is, I went into my back-end updateProduct() method and attempted to modify the Request.
First I tried a few methods such as:
//this one
$requestData = $request->all();
$requestData['number_of_searches'] = 123;
//also this one
$request->merge(['number_of_searches' => 123]);
//and this
$data = $request->all();
$data['number_of_searches'] = 123;
After countless hours, I am unable to modify the original request. After doing some research, it seems that requests are protected and cannot be modified, which makes sense. Therefore I attempted to create a new request that clones $request->all(), like this:
$new_request = new Request($request->all());
$new_request->merge(['number_of_searches' => 123]);
But I have failed to force to override 'number_of_searched'
My question is:
Should I stay away from FormData completely in this case? What method do you suggest to pass forms that have integers or floats or other datatypes through axios or fetch? Or what am I doing wrong? I find it hard to believe that FormData would only send strings (making parseInt useless before using axios). I'm sure I am doing something wrong from origin.
On the other hand, maybe I need to completely change my approach in my Controller when receiving the data. I am working on an app with a lot of fields and I love $request->all() because it simplifies what I am trying to do. I wouldn't mind using intval on the server side and that's it, but it seems overly complicated.
On the Vue side, you can use the number modifier on v-model to make sure it's not casting the value to a string:
v-model.number="product.number_of_searches"
On the request side, you can use $request->merge to override the value in a request
$request->merge([
'number_of_searches' => (int) $request->get('number_of_searches');
]);
At the model side in the updating hook within the boot method you can ensure the value is being casted as an int when saving:
static::updating(function ($model) {
$model->number_of_searches = (int) $model->number_of_searches;
});
This should give you the end to end.

Laravel & Ajax return array response no parsing

Currently I'm trying to pull some data via ajax and I'm not getting the data to appear properly.
In my ajax call I have this:
$.ajax({
url:"{{ route('pricing.fetch') }}",
method:"POST",
data:{select:select, value:value, _token:_token, dependent:dependent, productId:productId},
success:function(result)
{
$("ul[data-dependent='quantity']").html(result);
This works as expected. The problem is I'm trying to return data from different tables in my db. So I'm trying to do it by changing my result in ajax to this.
$("ul[data-dependent='quantity']").html(result.productQuantities);
The reason for me wanting to do this is because I have multiple drop downs I need. So I would also like to do another one like this:
$("ul[data-dependent='quantity']").html(result.productPaperStock);
my controller code is like this:
$data = Product::with(['productQuantity', 'productPaperstock'])->where('ID', $productId)->first();
// pull the quantity for this product
$productQuanties = $data->productQuantity;
$productPaperStock = 'hello';
$output = '';
foreach($productQuanties as $productQuantity)
{
$output .= "<li><span>" . $productQuantity->quantity_name . "</span></li>";
}
return response()->json["productQuanties" => $productQuanties, "productPaperStock" => $productPaperStock]);
I'm not sure what I'm doing wrong but using this example above I get a 500 error.
You need to set dataType: json option in your ajax request, and then in your controller, you can return json response.
Also, you are missing the starting brace in your controller code. The correct code is
return response()->json(["productQuanties" => $productQuanties, "productPaperStock" => $productPaperStock])
(Note that ...storage/logs/laravel.log is an awesome place to get insights into what's screwing your app:))

Laravel cannot access FormData from an HTTP POST request?

I'm having trouble getting values from my request when I set the content-type as multipart/form-data, but when I set the content-type as application/x-www-form-urlencoded everything works as expected. The values seem empty.
The request I sent via Postman:
Laravel API snippet:
use Illuminate\Http\Request;
...
public function foo(Request $req){
echo $req->get('some_key');
}
I've tried extracting the values via $req->get('key_name'), $req->key_name but to no avail. Calling the $req->all() method gives me the array with correct content but I have trouble extracting the values from it as well, is there a simpler way to achieve this? Thanks in advance.
When using multipart/form-data, set the action to PUT or PATCH and be sure to use the FormData object client side:
let Data = new FormData();
// using vuejs as an example of appending files.
Data.append( 'your_file', this.$refs.input.files[0], this.$refs.input.files[0].name );
Data.append('_method', 'PATCH');
axios.post('/api/foo', Data ).then( Response => {
// handle success
});

AJAX how to return a value

I know this is a question that's been asked to death, but I still struggle with how to use callbacks. I just want to return a value from the ajax's request.done outcome. I tried to follow Felix Kling's very informative answer on using callbacks with AJAX, but can't get my code to work.
My code below submits a form with user input data to the database. I would like it to retrieve the property employeeId. I am able to alert the correct value inside the submit function, but I would like to use this value in other functions. From reading up on asynchronous functions,i think this is because submit function exits before returning the value. I would really appreciate some guidance on using callbacks to return values.
I tried to only include the code pertaining to my issue
$('#employeeForm').submit(function(event,callback){
var values = $(this).serialize(); //gather form data
var result = foo(); //callback implementation from Felix Kling's SO answer
foo(function(result){
var request = $.ajax({
url: "game.php",
type:"post",
dataType:"json",
data: values
});
function foo(response.employeeId){ //I am trying to return value response.employeeIda in the success situation
request.done(function (response,textStatus,jqXHR){
document.getElementById("submitEmployeeInfo").innerHTML=response.employeeId;
var employeeId = response.employeeId;
}
});
})

Resources