AngularJS - How to send an audio file through $http post? - javascript

So I've been trying to send an audio file through an $http service using FormData, and so far what I have tried to send the file hasn't worked yet.
This is how the service looks like:
songs_services.add_new_song = function(new_song_name, new_song_artist, song) {
var fd = new FormData();
fd.append("new_song_name", new_song_name);
fd.append("new_song_artist", new_song_artist);
fd.append("song", song);
console.log(fd.get("new_song_name"));
console.log(fd.get("new_song_artist"));
console.log(fd.get("song"));
return $http.post(BACKEND_PREFIX + "add_new_song", fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
}).then(function() {
}, function() {
});
};
I wanted to make sure that the information was actually been appended to my FormData and this is what i get in the console:
So now I know that the FormData has actually the information that I need.
I have also tried changing the Content-Type to multipart/form-data with no success also.
I'm also using CakePHP 2 as my backend, so this is how I'm trying to get the information:
public function add_new_song() {
$this->autoRender = false;
$data = json_decode(file_get_contents("php://input"));
print_r($data);
print_r($_POST);
print_r($_FILES);
$new_song_name = $_POST["new_song_name"];
$new_song_artist = $_POST["new_song_artist"];
$song = $_FILES;
echo $new_song_name;
echo "<br />";
echo $new_song_artist;
echo "<br />";
print_r($song);
die();
}
But echoing the variables only shows empty arrays and I also get an undefined index error when trying to access the variables from $_POST.
Is there any special way I should be sending the audio file through $http? I really feel like I'm missing a little detail.

At last, instead of using angularjs $http.post I decided to try with $.ajax and see what happened, and it actually worked!
Here's what I used:
$.ajax({
type : "post",
url : "uploads/songs",
data : fd,
cache : false,
contentType : false,
processData : false,
success: function() {
console.log("Hey");
}
});

And in Angular 6, you can do the following to send audio as FormData.
Inject the HttpClient:
constructor(private http:HttpClient){}
Use the POST method to send audio:
let url = 'http://destinationurl.com/endpoint';
let formData = new FormData();
formData.append('myAudioFile',audioFile);
this.http.post(url,formData).subscribe(response => {
//handle response
}, err => {
//handle error
});
the post method will automatically change the content type to multipart, so you need not set anything manually.

Related

Where do PHP echos go when you are posting to a page?

This might be a dumb question. I'm fairly new to PHP. I am trying to get a look at some echo statements from a page I'm posting to but never actually going to. I can't go directly to the page's url because without the post info it will break. Is there any way to view what PHP echos in the developer console or anywhere else?
Here is the Ajax:
function uploadImage(image) {
var data = new FormData();
data.append("image", image);
imgurl = 'url';
filepath = 'path';
$.ajax({
url: imgurl,
cache: false,
contentType: false,
processData: false,
data: data,
type: "post",
success: function(url) {
var image = $('<img class="comment_image">').attr('src', path + url);
$('#summernote').summernote("insertNode", image[0]);
},
error: function(data) {
console.log(data);
}
});
}
And here is the php file:
<?php
$image = $_FILES['image']['name'];
$uploaddir = 'path';
$uploadfile = $uploaddir . basename($image);
if( move_uploaded_file($_FILES['image']['tmp_name'],$uploadfile)) {
echo $uploadfile;
} else {
echo "Unable to Upload";
}
?>
So this code runs fine but I'm not sure where the echos end up and how to view them, there is more info I want to print. Please help!
You already handle the response from PHP (which contains all the outputs, like any echo)
In the below code you have, url will contain all the output.
To see what you get, just add a console.log()
$.ajax({
...
success: function(url) {
// Output the response to the console
console.log(url);
var image = $('<img class="comment_image">').attr('src', path + url);
$('#summernote').summernote("insertNode", image[0]);
},
...
}
One issue with the above code is that if the upload fails, your code will try to add the string "Unable to upload" as the image source. It's better to return JSON with some more info. Something like this:
// Set the header to tell the client what kind of data the response contains
header('Content-type: application/json');
if( move_uploaded_file($_FILES['image']['tmp_name'],$uploadfile)) {
echo json_encode([
'success' => true,
'url' => $uploadfile,
// add any other params you need
]);
} else {
echo json_encode([
'success' => false,
'url' => null,
// add any other params you need
]);
}
Then in your Ajax success callback, you can now check if it was successful or not:
$.ajax({
...
dataType: 'json', // This will make jQuery parse the response properly
success: function(response) {
if (response.success === true) {
var image = $('<img class="comment_image">').attr('src', path + response.url);
$('#summernote').summernote("insertNode", image[0]);
} else {
alert('Ooops. The upload failed');
}
},
...
}
If you add more params to the array in your json_encode() in PHP, you simply access them with: response.theParamName.
Here is a basic example...
HTML (Form)
<form action="script.php" method="POST">
<input name="foo">
<input type="submit" value="Submit">
</form>
PHP Script (script.php)
<?php
if($_POST){
echo '<pre>';
print_r($_POST); // See what was 'POST'ed to your script.
echo '</pre>';
exit;
}
// The rest of your PHP script...
Another option (rather than using a HTML form) would be to use a tool like POSTMAN which can be useful for simulating all types of requests to pages (and APIs)

How to recieve image blob data by Cropper Js in laravel controller

I am working with cropper js and laravel, I cropped the image and put it into the formdata and send it to the Laravel controller by Jquery Ajax.
The problem it that I do not get data in controller. but only get an error.
the code is given below:
HTML
<button type="button" name="button" id="crop">Crop</button>
<img src="{{asset('public/img/img.jpg')}}" id="image" alt="" style="height: 500px;">
Jquery and Cropper Js Code
<script src="{{asset('public/js/jquery.min.js')}}"></script>
<script src="{{asset('public/js/cropper.min.js')}}"></script>
<script type="text/javascript">
$(document).ready(function(){
var ele = document.getElementById('image')
var cropper = new Cropper(ele);
$('#crop').on('click', function(){
var crop = cropper.getCroppedCanvas();
crop.toBlob(function(blob){
var formdata = new FormData();
console.log(blob);
formdata.append('croppedImage', blob);
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax("{{url('crop/save')}}", {
method: "POST",
data: formdata,
enctype: 'multipart/form-data',
cache: false,
processData: false,
contentData: false,
success(data){
console.log(data);
},
error(data){
console.log(data);
},
});
});
});
});
</script>
Laravel Route
Route::post('crop/save', 'CropperController#save');
Laravel Controller
public function save(Request $request){
$data = $request->croppedImage;
var_dump($data);
//Here I want to get image and upload it on the system
//But I cant Understand How
}
Error
<br />
<b>Warning</b>: Unknown: Input variables exceeded 1000. To increase the limit change max_input_vars in php.ini. in <b>Unknown</b> on line <b>0</b><br />
Please Guide me, How to done this in proper way.
Thanks in advance.
Regards,
You need to create a new image using the blob data and save that.
First, you need to get the actual contents of the image which is everything after: data:image/png;base64, or data:image/jpeg;base64,
(You can use the first part of the blob to get the extension type so you can save out the image using the same extension later.)
This will do that:
$base64Str = substr($data, strpos($data, ",")+1);
Next, you need to decode the contents as it is in base64
$file = base64_decode($base64Str);
Then, specify the path to save the new image. You can use a random generator combined with the current timestamp to get a unique name for each file.
public function generateUniqueFileName($extension)
{
return md5(uniqid(rand(), true)) . '-' . md5(microtime()) . '.' $extension;
}
$fullPath = 'public/images/' . $this->generateUniqueFileName($extension);
Finally, you can store the image to the specified path:
Storage::put($fullPath, $file);
You can try this too, since the url from your AJAX is a post request, go to app/Http/Middleware/VerifyCsrfToken.php and do this
protected $except = [
'crop/save'
];
Then in your controller you can save the image like this
public function fileUpload(Request $request){
$file = $request->file('croppedImage');
if($file) {
$file->move(public_path() .'/images', $filename);
}
}
OR
public function fileUpload(Request $request){
$file = $request->file('croppedImage');
if($file) {
Storage::disk('local')->put($filename, File::get($file));
}
}
If you are using the second way, don't forget to do this at the top of the controller'
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
The $filename variable is the name you choose to save the file with.

CakePhp: Got erros in response body when calling an API with the CakePHP HttpClient

I'm having some HTML text in my response from an API.
Response I got
Preview's response
Here is my code (PHP):
public function getBeatmapInformations() {
$this->render(false);
if($this->request->is('get')){
$url = $_GET['beatmapUrl'];
$isOsuUrlBeatmap = "#^(?:https://)?osu\.ppy\.sh/(?:b|beatmapsets)/(\d*)#";
if(preg_match($isOsuUrlBeatmap, $url, $matches)){
$OSU_API_KEY = "MY_API_KEY";
$httpClient = new Client();
$response = $httpClient->get('https://osu.ppy.sh/api/get_beatmaps', [
's' => intval($matches[1]),
'k' => $OSU_API_KEY
]
);
$result = $response->body();
if(!empty($result)){
echo $result;
}
}
}
}
Javascript side (AJAX request):
function launchAjaxRequest(beatMapUrl) {
let url = beatMapUrl.replace(/['"]+/g, '');
$.get({
type : "GET",
url: '/ofv/getBeatmapInformations',
data: {
beatmapUrl : url,
},
success: function(data){
fillModesAvailablesForBeatmap(data);
}
});}
You should not manually echo anything in your controllers actions in CakePHP. The way to achieve json output in CakePHP is to use Data Views with Request Handler:
1.Enable Request Handler in your controller's initialize() method:
public function initialize(){
$this->loadComponent("RequestHandler");
}
2.In your action, set your data to be serialized:
$result = $response->body();
$this->set(compact("result"));
$this->set("_serialize", "result");
More about Request Handler and Data Views can be found in docs: JSON and XML views
As probably someone will point it out, you have also an alternative here: you can simply stop execution of script right after echoing data with die(). But it is not the Cake way of handling this.

Angular $http.jsonp() method works only once

Response is succeded (alert->done), but second and another hits will response 'error'.
I've tried to add some config params with 'cache: false' but still works only first time. Should I clear some cache/history or sth?
$scope.add2 = function() {
var config = {
//url : 'http://www.***.pl/index.php/json/getallusers',
cache: false,
//type : 'POST',
crossdomain: true,
//callback: 'JSON_CALLBACK',
//data: d,
contentType: "application/json",
dataType: "jsonp",
};
var r = Math.floor(Math.random() * 1000) + 4;
var d = {user_type_id:0, user_venue_id:0, fname:r};
var e = objToString(d);
//$http.jsonp('http://www.***.pl/index.php/json/adduserget?callback=JSON_CALLBACK&'+ e, config)
$http.jsonp('http://www.***.pl/index.php/json/adduserget?callback=JSON_CALLBACK&'+ e)
.success(function(res){
console.log('res:' + res.user);
alert('done');
})
.error(function(){
console.log('error');
alert('error');
});
};
This is the new question in jsonp and post action in ionic framework (angular.js)
I've added to server response 'angular.callbacks._0(' before json data... maybe here's mistake?
This is solution for my issue:
now i'm dynamiccaly getting the callback parameter which can by vary (not always angular.callback_0, but can be: angular.callback_1, angular.callback_2, etc.) from GET method at a server and put it before response data f.e in php:
<?php header('content-type: application/json;');
$json=json_encode($result);
echo $_GET['callback'].'('.$json.')';
?>
Issue is because url is getting cached in browser and the other time it will fetch from the cache.So I'd suggest you to add new dummy parameter inside you URL that will have current Date.now() so that every time you call service that will make URL unique doe to Date.now() component.
Code
$http.jsonp('http://www.where2play.pl/index.php/json/adduserget?callback=JSON_CALLBACK&'+
e + '&dummy='+ Date.now()) //<--this will add new value everytime to make url unique

ajax request all return error 500

When ever I am doing an ajax request with jquery I always get an error 500 return,
I am posting to the following URL
http://localhost/domain/index.php/my_profile/interests_music
using this javascript,
$("#add").click(function(e){
//set some process variables, we need to get the forms action,
//and any post data it is sending appending isAjax into the params
//gives us a point in the controller to gracefully check for ajax.
var action = $(this).parent('form').attr('action');
var formData = $(this).parent('form').serialize()+"&isAjax=1";
$.ajax({
type: "POST",
url: action,
data: formData
}).done(function( msg ) {
alert( "Data Saved: " + msg );
});
e.preventDefault();
});
The params that are being sent are,
music=Savage Garden&isAjax=1
And the PHP method the ajax is requesting looks like this,
public function interests_music()
{
if($this->input->post('music'))
{
$this->rest->initialize(array('server' => 'https://www.googleapis.com/freebase/v1'));
$response = $this->rest->get('mqlread?query={"type":"/music/artist","name":"' . urlencode($this->input->post('music')) . '","id":[]}');
$data['image'] = 'https://usercontent.googleapis.com/freebase/v1/image'.$response->result->id[0].'?mode=fillcrop&maxwidth=80&maxheight=80';
$data['category'] = 'music';
$data['user_id'] = $this->session->userdata('id');
$data['name'] = $this->input->post('music', TRUE);
$this->profile_model->add_interest($data);
Events::trigger('interests_music');
Events::trigger('badge_stagediver');
if($this->input->post('isAjax') == 1)
{
echo json_endcode($data);
$this->_buttons();
}
redirect('my_profile/interests');
}
else
{
show_404();
}
}
Am I missing something, is this a common problem?
Well for one there's a typo in your PHP which could be what your server is choking on: echo json_endcode($data); should be echo json_encode($data);. Aside from that there could be other issues with your HTTP server. What server are you using? A good practice is to find the server error log and PHP error log and use tail -f or some other method of monitoring the logs which should give you more information when you have 505s.

Categories

Resources