Angular $http.jsonp() method works only once - javascript

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

Related

Trying to pass deflated chunk size for Ajax loading progress bar, but can't set headers

When loading .php files through Ajax, I want to show how far the progress is rather than just the default spinner method $("#loader").css("display", "none"); .
Now as I have been building this, I have learnt that Chrome sends chunked data so the content-length parameter is not easily populated. There are a million questions on here about this as well.
So I am looking at the solution here from Nat and trying to set a header myself that will eventually contain the file size. I haven't even gotten to getting the full decompressed value to pass into the customer header (next bridge to cross) as I am trying to just pass a static value right now to check that the below JS works. You can see I am setting a value of 333 below. I have tried the same with headers: as you can see commented out in the first line. Both methods set the headers but I dont get them when trying to log them into console to check why contentLength is always NaN.
FYI I have commented out //progressIndicator.update(e.loaded / contentLength); below to avoid it crashing on error but will restore this part once I can actually get a byte value from the server.
$.ajax({
//headers: { 'x-decompressed-content-length': '333' },
xhr: function () {
var xhr = new window.XMLHttpRequest();
xhr.addEventListener("progress", function (evt) {
var contentLength;
if (evt.lengthComputable) {
contentLength = evt.total;
} else {
console.log('all: ' + xhr.getAllResponseHeaders());
contentLength = parseInt(evt.target.getResponseHeader('x-decompressed-content-length'), 10);
}
//progressIndicator.update(e.loaded / contentLength);
});
return xhr;
},
beforeSend: function (xhr){
xhr.setRequestHeader('x-decompressed-content-length', '333');
},
url: cyberAjax.ajaxurl,
data: ({
action: 'ajax_load_tabs',
id: tab_id,
userid: userid,
}),
success: function(data){
$(tab_id).html(data);
},
error: function(data)
{
console.log("Error!");
return false;
}
});
Here you can see the header is set when I check the XHR requests in Network tab:
But when I use the console.log in the script above to retrieve all headers, there is no sign of them (and so my contentLength is always NaN):
Any thoughts?

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

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.

AJAX not coming up a success even though its updating the database

My php is updating the table but not refreshing in javascript have tried several different ways of doing this and nothing is working.
PHP
$sql = "UPDATE INTOXDM.ASTP_FORM SET SUPERVISOR_EID = '".$newSuper."' WHERE FORMID = '".$formId."'";
$row = $xdm->fetch($sql);
$return["color"] = $row['APPRENTICE_SIGNATURE'];
$return["json"] = json_encode($return);
echo json_encode($return);
?>
Javascipt
var data = {
"formId": formID,
"newSuper": newSuper
};
data = $.param(data);
$.ajax({
type: "POST",
dataType: "json",
url: "src/GetInfo.php",
data: data,
success: function() {
location.reload();
}
});
I'd start by modifing the code like this:
var data = {
"formId": formID,
"newSuper": newSuper
};
// No need for serialization here,
// the 'data' parameter of jQuery.ajax accepts JS object
// data = $.param(data);
$.ajax({
type: "POST",
dataType: "json",
url: "src/GetInfo.php",
data: data,
// As suggested by Rocket Hazmat, try to add an error callback here
error: function(jQueryXHR, textStatus, errorMessage) {
console.log("Something went wrong " + errorMessage);
},
success: function(jsonResponse) {
// Try to reference the location object from document/window
// wd = document or window as seen here http://stackoverflow.com/questions/2624111/preferred-method-to-reload-page-with-javascript
// Also watch out, usually browsers require a user confirmation before reloading if the page contains POST data
// One of these should be fine
wd.location.assign(wd.location.href) : go to the URL
wd.location.replace(wd.location.href) : go to the URL and replace previous page in history
wd.location.reload(<true/false/blank>) : reload page from server/cache/cache
}
});
Also, this might be a shot in the dark but the parameter dataType gave me problems sometime in the past, so if you are sure about the json returned by your php script, you could use the eval function to jsonify the response
$.ajax({
...
// Remove data type
// dataType: "json",
...
success: function(plainTextResponse) {
// Eval response, NOT SAFE! But working
var jsonResponse = eval('('+ plainTextResponse +')');
...
}
});
Your ajax is expecting json data and your php is sending malformed json string. Send a correct json string and your script will work fine.
Your php json_encode should be like this:
$data = json_encode($return);
echo $data;

Extract data from current URL and use it in ajax call as a paramenter

I am developing a website in which only 1 html page is there in which I first fethch the url & gets the id from url and send it to api using ajax call. On success, I displays data of the given id from url.My code is as-
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$('#main').hide();
var url = window.location.href;
var formno = url.substr(url.lastIndexOf('/') + 1);
if (formno != 'Login.html') {
var apiUrl = 'http://localhost:801/api/api/Patient/Get';
$.ajax({
url: apiUrl,
crossDomain: true,
contentType: "application/json",
type: 'GET',
data: { formNo: formno },
success: function (result) {
$('#main').show();
alert("Success" + result)
},
error: function (result) {
alert("error :: " + JSON.stringify(result))
}
});
}
});
</script>
when I use the url as abc.in#1 it displays the success alert but I want to give the url in format abc.in/1 at that time it gives
HTTP Error 404.0 - Not Found
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
Why it can not find the page? Is there any solution for this?
I want to give plain url as abc.in/1 where 1 is id and which is dynamic.
Is there any solution?
Your browser is probably trying to access document on location abc.in/1, which doesn't exist. You will need some server side logic for this, e.g. php router which will always serve your document, and additonal parameters will be processed by it. abc.in#1 anchor is different type of url parameter, which purpose is to be processed by document or javascript on client side.

JSON Response {"d":"128.00"} but displaying "128"

I have been working on a shopping cart that the user can add/remove order items as they please and am returning an updated sub-total via a webservice using jQuery $.ajax
Here is how I am calling the webservice and setting the sub-total with the response.
//perform the ajax call
$.ajax({
url: p,
data: '{' + s + '}',
success: function(sTotal) {
//order was updated: set span to new sub-total
$("#cartRow" + orderID).find(".subTotal").text(sTotal);
},
failure: function() {
//if the orer was not saved
//console.log('Error: Order not deleted');
}
});
The response I am getting seems perfectly fine:
{"d":"128.00"}
When I display the total on the page it displays as 128 rather than 128.00
I am fully sure it is something very simple and silly but I am so deep into it now I need someone with a fresh brain to help me out!!
Cheers :)
EDIT
I am also using $.ajaxSetup to set the correct contentType:
$.ajaxSetup({
type: "POST",
contentType: "application/json; charset=utf-8",
data: "{}",
dataFilter: function(data) {
var msg;
if (typeof (JSON) !== 'undefined' &&
typeof (JSON.parse) === 'function')
msg = JSON.parse(data);
else
msg = eval('(' + data + ')');
if (msg.hasOwnProperty('d'))
return msg.d;
else
return msg;
}
});
That is because the value is treated as a number, while you want it treated as a string.
When you are using '.. .text(sTotal)', you are actually calling the .toString() method on the Number object wrapping the primitive sTotal. And since this is a whole number, it displays it without decimals.
You need to use a format the number as a string prior to calling .text(foo) for the number to be formatted like that.
This will give you two decimals
var a=1/3;
a = a.toString();
switch(a.lastIndexOf(".")){
case -1:
a+=".00";
break;
case a.length-2:
a+="0";
break;
default:
a=a.substring(0, a.indexOf(".") + 3);
}
alert(a);
I don't see anywhere in this code where you access the d property of the response.
Perhaps you mean to do this?
$("#cartRow" + orderID).find(".subTotal").text(sTotal.d);
// --------------------------------------------------^^
EDIT
Ok, I see the problem. You're returning JSON but not defining a dataType in the $.ajax() call. This means that jQuery sees your application/json mimetype and interprets the response as JSON. 128.00 in JSON is a Number, not a String. However, "128.00" would be a String.
In order to keep this working, You need to format the response before printing it (as others have suggested), or adjust your endpoint to return a valid JSON string.
Here's my test to prove the solution
<div id="test">
Subtotal <span class="subTotal"></span>
</div>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript" charset="utf-8">
google.load("jquery", "1.4.2");
</script>
<script type="text/javascript" charset="utf-8">
$.ajax({
url: 'test.php',
data: {},
success: function(sTotal) {
//order was updated: set span to new sub-total
$("#test").find(".subTotal").text(sTotal);
}
});
</script>
and test.php
<?php
header( 'Content-type: application/json' );
echo '128.00';
Output
Subtotal 128
But when I change test.php to be this
<?php
header( 'Content-type: application/json' );
echo '"128.00"';
The expected output is generated
Subtotal 128.00
Or, you could alternatively tell jQuery to treat the response as text by specifying a dataType parameter, for example
$.ajax({
url: 'test.php',
data: {},
dataType: 'text', // <---- here
success: function(sTotal) {
//order was updated: set span to new sub-total
$("#test").find(".subTotal").text(sTotal);
}
});
EDIT 2
Ok, after messing with this some more, I see what's going on. The dataFilter handler you defined converts the response into JSON itself, and in this case, returns the string 128.00. However, jQuery still applies the intellgent-guessed dataType (which is JSON) to this value before sending it to the success handler.
There are a multitude of ways to fix this, all of which depend on what other AJAX calls your application relies on this setup for. The quick-fix I applied in my test was to do this
$.ajaxSetup({
type: "POST",
contentType: "application/json; charset=utf-8",
data: "{}",
// define the text data type so that we return data.d, jQuery doesn't parse it as JSON again
dataType: 'text',
dataFilter: function(data) {
data = $.parseJSON( data ); // Use jQuery's parsing
if (data.hasOwnProperty('d'))
{
return data.d;
}else{
return data;
}
}
});
But that may not work across the board for you
Please try this:
$("#cartRow" + orderID).find(".subTotal").text(sTotal.toFixed(2));
HTH

Categories

Resources