I have a simple API call that sets the state of a list array with its response. I was wondering how I would go about implement a try/catch or error message if there is a bad search (i.e like a typo) or if the array is not set with the response. The code snippet is below:
componentDidMount() {
this.search('https://itunes.apple.com/search?term=modern_baseball');
}
search(URL) {
return $.ajax({
type: 'GET',
dataType: 'json',
url: URL,
success: function (response) {
this.showResults(response);
}.bind(this),
error: function() {
alert("Error handling request");
}
});
}
showResults(response) {
console.log(response);
this.setState({
searchResults: response.results,
moveResults: []
});
}
Try something like this:
componentDidMount() {
this.search('https://itunes.apple.com/search?term=modern_baseball');
}
search(URL) {
let self = this; //avoid the .bind call and store a ref to the current context for use inside the ajax handlers.
return $.ajax({
type: 'GET',
dataType: 'json',
url: URL,
success: function (response) {
self.showResults(response);
},
error: function() {
alert("Error handling request");
self.setState({error: "Error handling request", moveResults:[], searchResults:[]}); //set the state directly if there is an error
}
});
}
showResults(response) {
console.log(response);
this.setState({
searchResults: response.results,
moveResults: []
});
}
It sets a variable (self) to the current context (this) and then calls the setState directly in the error handler for the ajax call. Alternatively you could define a callback function just like you do for the success handler.
Related
I am trying to setState of a component after a ajax callback receives data from REST api. here's my code for the component constructor
constructor(props) {
super(props);
this.state = { posts: [] };
this.getPosts = this.getPosts.bind(this);
}
Then I have a componentDidMount method that looks like following.
componentDidMount() {
this.getPosts();
}
Now here's my getPosts function where I am doing the ajax request.
getPosts = () => {
$.ajax({
type: 'get',
url: urlname,
success: function(data) {
this.setState( { posts: data } )
}
});
}
I am tying to set the State but I am getting the following error.
this.setState is not a function
Not really sure what is causing this. It would be really helpful if someone points me to the right direction. Thanks in advance.
Bind the callback function also so that this inside the callback points to the context of the React Component and not the callback function
getPosts = () => {
$.ajax({
type: 'get',
url: urlname,
success: (data) => {
this.setState( { posts: data } )
}
});
}
or you could use bind like
getPosts = () => {
$.ajax({
type: 'get',
url: urlname,
success: function(data) {
this.setState({ posts: data })
}.bind(this)
});
}
The issue is related with loosing context of this.
Please try this:
let self = this;
getPosts = () => {
$.ajax({
type: 'get',
url: urlname,
success: function(data) {
self.setState( { posts: data } )
}
});
}
or you can use bind:
getPosts = () => {
$.ajax({
type: 'get',
url: urlname,
success: function(data) {
self.setState( { posts: data } )
}
});
}.bind(this)
You have to store the context into a variable as "this" reference will not be available in the callback. Try below solution:
getPosts = () => {
let that=this;
$.ajax({
type: 'get',
url: urlname,
success: function(data) {
that.setState( { posts: data } )
}
});
}
I'm sending ajax call and getting an answer that I need from the first ajax then I want to pass my result to my nested ajax, my var (result) is null in the nested ajax/settimeout fun, can I pass it ? Am I missing something ?
$.ajax({
url: '#Url.Action("getCustomerGuidId", "Document")',
type: 'POST',
cache: false,
data: { "classNum": currentclassNum},
contentType:'json' ,
dataType:'text',
success: function (result) {
alert(result);**-> is fine - not null**.
// a or result is null when I hit the getCurrentDoc- function althought I get the data I need from getCustomerGuidId function
var a = result;-> tried to pass it to a new var..IDK.. I
thought it will help... it didn't.
setTimeout(function () {
$.ajax({
type: "GET",
url: '#Url.Action("getCurrentDoc", "Document")',
contentType:'text',
data: a,-> here it's null
success: function (data) {
}
});
}, 2000);
},
error: function (result) {
alert("fail " + result);
}
});
You can try something like this will help to pass value to nested ajax call
function test(){
var myText = 'Hello all !!';
$.get({
//used the jsonplaceholder url for testing
'url':'https://jsonplaceholder.typicode.com/posts/1',
'method':'GET',
success: function (data) {
//updating value of myText
myText = 'welcome';
$.post({
'url':'https://jsonplaceholder.typicode.com/posts',
'method':'POST',
//data.title is the return value from get request to the post request
'data':{'title':data.title},
'success':function (data) {
alert(data.title +'\n' + myText);//your code here ...
}
});
}
});
}
An old question and you've likely moved on, but there's still no accepted answer.
Your setTimeout takes an anonymous function, so you are losing your binding; if you have to use a Timeout for some reason, you need to add .bind(this) to your setTimeout call (see below)
setTimeout(function () {
$.ajax({
type: "GET",
url: '#Url.Action("getCurrentDoc", "Document")',
contentType:'text',
data: a,
success: function (data) {
}
});
}.bind(this), 2000);
At a guess you're using a Timeout because you want to ensure that your promise (i.e. the first ajax call) is resolving prior to making the nested call.
If that's your intention, you can actually scrap setTimeout completely as you have the nested call in the first ajax success call, which only runs once the promise has been resolved (providing there isn't an error; if so, jQuery would call error rather than success)
Removing setTimeout means you won't lose your binding, and a should still be result (hopefully a is an object, otherwise your second call is also going to experience issues...)
Lastly, after overcoming the binding issue you wouldn't need var a = result; you should be able to pass result directly to your nested ajax call.
Good luck!
In the nested ajax you send a as a param name, not as a param value.
So you can try the following (change param to actual param name which your server expects):
$.ajax({
url: '#Url.Action("getCustomerGuidId", "Document")',
type: 'POST',
cache: false,
data: { "classNum": currentclassNum},
dataType:'text',
success: function (result) {
setTimeout(function () {
$.ajax({
type: "GET",
url: '#Url.Action("getCurrentDoc", "Document")',
data: {param: result},
success: function (data) {
}
});
}, 2000);
},
error: function (result) {
alert("fail " + result);
}
});
I am trying to get json via ajax and if my response variable is acceptable redirect using react router. How can I achieve that?
successRedirect(){
if (this.responseCode.equals("what I need")) {
router.transitionTo('/')
}
}
createCheckout() {
$.ajax({
url: "someurl",
dataType: 'json',
type: 'POST',
cache: false,
data: this.data,
success: function(response) {
this.setState({
response: response,
responseCode: response.result.code
});
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
})
}
Function must be called after response is taken. For example I have this code and in render response is taken and shown after some time:
render(){
return (
<div>
<div>Response - {this.state.responseCode}</div>
</div>
);
}
It appears the issue was with this line:
if (this.responseCode.equals("what I need")) {
Items that get added via this.setState are available on the this.state object. Also JavaScript does not supply an equals function, but you can do comparisons with ===
if (this.state.responseCode === "what I need") {
I have one html element (elem1) and 2 JS functions (func1, func2) that hides and shows elem1 respectively. These JS functions make individual ajax calls and func2 is calling func1 internally.
Problem: I need to call func2, which internally calls func1. Calling func1 hides elem1. After calling func1, I want to show elem1. But this show is not working.
JSFiddle: https://jsfiddle.net/46o93od2/21/
HTML:
<div id="elem">
Save ME
</div>
<br/>
<button onclick="func1()" id="func1">Try Func1</button>
<button onclick="func2()" id="func2">Try Func2</button>
JS:
function func1() {
$.ajax({
url: '/echo/json/', //use the correct processing url here
type: "POST",
data: {}, // send in your data
success: function (data) {
//var aData = JSON.parse(data); // there is no data to parse
$('#elem').hide();
},
error: function (xhr, errmsg, err) {
alert('error');
}
});
}
function func2() {
$.ajax({
url: '/echo/json/', //use the correct processing url here
type: "POST",
data: {}, // send in your data
success: function (data) {
//var aData = JSON.parse(data); // there is no data to parse
func1();
$('#elem').show();
},
error: function (xhr, errmsg, err) {
alert('error');
}
});
}
Make func1 take a callback function that tells it what to do after it gets the response. func2 can pass a function that shows the element.
function func1(callback) {
$.ajax({
url: '/echo/json/', //use the correct processing url here
type: "POST",
data: {
json: ''
}, // send in your data
success: function(data) {
if (callback) {
callback();
} else {
$('#elem').hide();
}
},
error: function(xhr, errmsg, err) {
alert('error');
}
});
}
function func2() {
$.ajax({
url: '/echo/json/', //use the correct processing url here
type: "POST",
data: {
json: ''
}, // send in your data
success: function(data) {
func1(function() {
$('#elem').show();
});
},
error: function(xhr, errmsg, err) {
alert('error');
}
});
}
DEMO
So I have had to modify some old existing code and add another ajax event to onclick
so that it has onclick="function1(); function2();"
This was working fine on our testing environment as it is a slow VM but on our live environment it causes some issues as function1() has to finished updating some records before function2() gets called.
Is there a good way to solve this without modifying the js for function2() as this the existing code which is called by other events.
Thanks
Call function2 upon returning from function1:
function function1() {
$.ajax({
type: "POST",
url: "urlGoesHere",
data: " ",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
//call function2
},
error:
});
}
Or wrap them in a function that calls both 1 and 2.
You need to use always callback of ajax method, check out always callback of $.ajax() method http://api.jquery.com/jquery.ajax/.
The callback given to opiton is executed when the ajax request finishes. Here is a suggestion :
function function1() {
var jqxhr = $.ajax({
type: "POST",
url: "/some/page",
data: " ",
dataType: "dataType",
}).always(function (jqXHR, textStatus) {
if (textStatus == 'success') {
function2();
} else {
errorCallback(jqXHR);
}
});
}
I'm assuming you use Prototype JS and AJAX because of your tags. You should use a callback function:
function function1(callback) {
new Ajax.Request('http://www.google.nl', {
onSuccess: function(response) {
callback();
}
});
}
function function2(callback) {
new Ajax.Request('http://www.google.nl', {
onSuccess: function(response) {
callback();
}
});
}
function both() {
function1(function() {
function2();
});
}
Then use onclick="both();" on your html element.
Example: http://jsfiddle.net/EzU4p/
Ajax has async property which can be set false. This way, you can wait for that function to complete it's call and set some value. It actually defeats the purpose of AJAX but it may save your day.
I recently had similar issues and somehow calling function2 after completing function1 worked perfectly. My initial efforts to call function2 on function1 success didn't work.
$.ajax({
type: "POST",
url: "default.aspx/function1",
data: "",
contentType: "application/json; charset=utf-8",
dataType: "json",
async: false, // to make function Sync
success: function (msg) {
var $data = msg.d;
if ($data == 1)
{
isSuccess = 'yes'
}
},
error: function () {
alert('Error in function1');
}
});
// END OF AJAX
if (isSuccess == 'yes') {
// Call function 2
}