I have a function which uses jquery to call API and get a result. My API end is programmed to return the number "19" just for testing.
export function clientAdd(data) {
return (dispatch) => {
return $.ajax({
url: "http://api.example.com/client/add/",
headers: {'AUTHORIZATION': `${sessionStorage.jwt}`},
type: 'POST',
cache: false,
data: data,
dataType: 'json',
success: function (data) {
let redirectUrl = '/client/' + data
return redirectUrl';
},
error: function(xhr, status, err) {
if (xhr.status === 401) {
sessionStorage.removeItem('jwt');
return '/signin';
}
console.log('xhr',xhr.responseText);
console.log('status',status);
console.log('err',err);
return dispatch({type: GET_CLIENT_FAIL, err});
}
})
}
}
Then in my component, upon clicking on the submit button, it will call the onSave function as follows
onSave(event) {
//event.preventDefault();
this.props.actions.clientAdd(this.state.credentials).then((result) => {
return this.setState({redirect: true, newCustomerId: result})
}).catch((result) => {
return this.setState({redirect: false, errorMessage: result})
});
}
Where the result is supposed to be the redirectUrl or ErrorMessage.
However, I'm keep getting the number 19 which is returned by my API.
I read online if I want to use promise in my component, i have to add return infront of $.ajax, if not "then" will be undefined.
What you can do is, create your own promise and put the ajax call inside it
Then call resolve and pass data that you want when then is called
resolve(data_passed_to_then)
Like this :
return new Promise((resolve,reject) => {
$.ajax({
...
success: function (data) {
let redirectUrl = '/client/' + data
resolve(redirectUrl);
},
error: function(xhr, status, err) {
...
// return dispatch({type: GET_CLIENT_FAIL, err});
reject(err);
}
})
})
Related
i built a registration form and validated it using javaScript. but i want after a user filled the form, it should post to the server. i am confused on where to place my httpRequest function. i don't know if its after validation or inside the validation function
This is my validation function
function formregister(e){
if (first_name.value=== "" || last_name.value=== "" || user_id.value==="" || id_type.value=== ""
|| id_no.value=== "" || address.value==="" || !terms.checked) {
var fPassResult = '1';
} else{
var fPassResult = '0';
}
if(fPassResult === "1") {
window.location = "register.html";
}else{
Swal.fire({
type: 'success',
title: 'Your Registration has been Submitted Successfully',
text: 'Click Ok to Login',
timer: 10000
}
).then(function(){
window.location="Login.html";
})
}
e.preventDefault();
};
**And this is my post request function**
function registerationApiCall(e){
var data = {
"user_id":"user_id.value",
"user_pin": "user_pin.value",
"first_name":"first_name.value",
"last_name":"last_name.value",
"address":"address.value",
};
fetch("jehvah/api",{
type : 'POST',
data : data,
dataType : 'JSON',
encode : true,
success: function (response, status, xhr) {
if (result==="OK") {
console.log("success");
}else{
console.log("bad");
}
},
error: function (xhr, status, error) {
console.log("something went wrong");
}
});
}
Please kindly check my post request function, i dont know if i am doing it the right way
Hi ✌ when fPassResult === "0" in this case inside else{} call registerationApiCall()
you tell the user it's a success after you get OK from the server which is Asynchronous call
& inside fetch response you call swal.fire
for this code to work your server when checks the database & every thing is ok returns a msg like this {"msg":"OK"}
CODE:
else{
registerationApiCall()
}
function registerationApiCall becomes
fetch('jehvah/api',
{ method: 'POST',headers: {'Content-Type': 'application/json'}, body: JSON.stringify(data)})
.then((response) => response.json())
.then((result) => {
console.log('Success:', result);
if (result.msg="OK") {
console.log("success");
Swal.fire({
type: 'success',
title: 'Your Registration has been Submitted Successfully',
text: 'Click Ok to Login',
timer: 10000
}).then(function(){window.location="Login.html";})
}else{ console.log("usres exsists / etc");}
})
.catch((error) => {
console.log("something went wrong");
});
}
Also in the request payload you sent a group of strings not the variables containing the form values
Here
var data = {
"user_id":"user_id.value",
"user_pin": "user_pin.value",
"first_name":"first_name.value",
"last_name":"last_name.value",
"address":"address.value",
};
Change that to
var data = {
"user_id":user_id.value,
"user_pin": user_pin.value,
"first_name":first_name.value,
"last_name":last_name.value,
"address":address.value
};
Looking at the fetch documentation (https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch), success and error does not exists.
The fetch function returns a Promise, so you can handle results as any Promise should do:
fetch("jehvah/api", {
method: 'POST',
body : JSON.stringify(myDataObject)
})
.then(blob => blob .json())
.then(result => console.log('Success!!))
.catch(e => console.log('Failure :('))
I import the function getWeather from another .js file I've written. The result is a json blob. I've verified that I get the JSON blob back, but when I try to call the getWeather function and use .then to wait for a response and set my state I get a TypeError.
getWeather(parseFloat(lat),parseFloat(long)).then((data) =>{
this.setState({weatherType: data.currently.icon, temp: data.currently.temperature})
return data
}).catch((error) => {
console.log(error.message);
})
The getWeather function is here:
export function getWeather(lat,long) {
const params = {
headers: {
"content-type": "application/json; charset=UTF-8",
"Access-Control-Allow-Origin": "*"
},
method: "GET"
};
fetch(`https://api.com/mykey/${lat},${long}`, params)
.then(function (data) {
return data.json();
})
.then(res => {
console.log(res);
})
.catch(error => {
console.log(error);
});
}
You need to return fetch() in order to make the promise accessible from another function. Also, I would probably handle logging and errors in the calling function as when you log the data you are no longer returning it.
export function getWeather(lat,long) {
const params = {
headers: {
"content-type": "application/json; charset=UTF-8",
"Access-Control-Allow-Origin": "*"
},
method: "GET"
};
return fetch(`https://api.com/mykey/${lat},${long}`, params)
.then(function (data) {
if (!data.ok) { return new Error('custom error message here') }
return data.json();
});
}
You are most probably return that blob from the getWeather function without creating a Promise.
Try something like this:
function getWeather() {
// create blob as usual
return Promise.resolve(blob);
}
or if you already inside a then you must just retrun something from it:
fetch(`https://api.com/mykey/${lat},${long}`, params)
.then(function (data) {
return data.json();
})
.then(res => {
console.log(res);
retrun res; // return something
})
.catch(error => {
console.log(error);
});
}
So I have this function that gets the user details via UUID;
function getUserDetails(uuid){
$.ajax({
url:'http://localhost/hrms/controller/php/getUserDetails.php',
method: 'POST',
dataType: 'json',
data: { uuid: uuid },
success:function(result){
console.log(result);
},
error: function(xhr, status, error){
if(xhr.status == 401){
toastr.error(xhr.responseText);
}
}
});
}
which give me the result of
AJAX RESULT
Now I wonder how to access that data. The function is from different js page. How can I throw the json result to another js page?
Im using JQUERY. Thanks and more powers.
When you use ajax it takes some time to return the data form server to client, so you can use promise or callbacks:
Callbacks:
function.js
function getUserDetails(uuid, callback){
$.ajax({
url:'http://localhost/hrms/controller/php/getUserDetails.php',
method: 'POST',
dataType: 'json',
data: { uuid: uuid },
success:function(result){
callback(result);
},
error: function(xhr, status, error){
if(xhr.status == 401){
toastr.error(xhr.responseText);
}
}
});
}
index.js
getUserDetails(uuid, function(data){
console.log(data);
});
Promises
function.js
function getUserDetails(uuid){
return new Promise((resolve, reject) => {
$.ajax({
url:'http://localhost/hrms/controller/php/getUserDetails.php',
method: 'POST',
dataType: 'json',
data: { uuid: uuid },
success:function(result){
resolve(result);
},
error: function(xhr, status, error){
if(xhr.status == 401){
toastr.error(xhr.responseText);
}
const reason = new Error('Error');
reject(reason);
}
});
});
}
index.js
getUserDetails(uuid).then(function(data){
console.log(data);
});
I have two functions,
function getRequest(url, api_key, callback) {
$.ajax({
url: url,
contentType: 'application/json',
type: 'get',
beforeSend: function(xhr){
xhr.setRequestHeader('Authorization', 'Bearer ' + api_key);
},
success: function(response) {
callback(response);
},
error: function(error) {
console.log(error);
document.getElementById("droplets").textContent = error;
}
});
}
function getDroplets(url, api_key) {
var request = getRequest(url, api_key, function(response) {
var droplets = response.droplets;
var numDroplets = droplets.length;
return {
droplets: droplets,
numDroplets: numDroplets
};
});
alert(request);
}
I want to have another function, let's call it listDroplets, that will call getDroplets() and manipulate the data returned from it. I'm not sure how to do this because getDroplets has an asynchronous call within it.
EDIT: I have tried the following, but it still doesn't work.
async function listDroplets() {
await getDroplets(api_url, api_key);
alert(request.numDroplets);
}
Here are how your functions could return promise like objects that you can use in an async await function:
function getRequest(url, api_key, callback) {
//to escape terrible jQuery Deferred and comfortably continue in Promise land
// you can do
// const deferred = $.ajax(...); return Promise.resolve(deferred)
return $.ajax({//return promise like object
url: url,
contentType: 'application/json',
type: 'get',
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', 'Bearer ' + api_key);
}
});
}
function getDroplets(url, api_key) {
return getRequest(url, api_key)//return promise like object
.then(function (response) {//
var droplets = response.droplets;
var numDroplets = droplets.length;
return {
droplets: droplets,
numDroplets: numDroplets
};
})
.catch(function (error) {//implement error if something goes wrong
console.log(error);
document.getElementById("droplets").textContent = error;
});
}
async function listDroplets() {
//depending on how old your jQuery is you may want to do this:
// await Promise.resolve(getDroplets(api_url, api_key));
const request = await getDroplets(api_url, api_key);
//note that if something goes wrong then request is undefined (depending on jQuery version)
alert(request.numDroplets);
}
I have following function, which returns promise for authentication
authenticate: function(options) {
return new Promise((resolve, reject) => {
$.ajax({
url: this.tokenEndpoint,
type: 'POST',
headers: {'Content-Type': 'application/json', 'Accept-Encoding': 'gzip, deflate'},
data: JSON.stringify({
username: options.identification,
password: options.password
})
}).then(function(response) {
console.log(response) // I get here object with good properties
resolve({
lastLoginDate: response.lastLoginDate,
login: response.login,
name: response.name,
role: response.role,
token: response.id_token
});
}, function(xhr, status, error) {
if(error !== undefined) {
console.log(error);
}
var response = xhr.responseText;
reject(response);
});
});
When i call it and pass good username and password it returns "undefined", but when i pass bad properties, my "reject" works perfectly . Does someone know why my "then" doesn't return expected output?
this.get('session').authenticate('authenticator:custom', {'identification': identification, 'password': password})
.then((data)=>{
console.log(data); //Undefined <- here is my problem.
})
.catch((reason) => {
console.log(reason); // It works, when pass bad password!
this.set('errorMessage', reason.error);
});
Firstly, $.ajax returns a jQuery Promise which these days is 99.999% as good as a native Promise - so no need to wrap $.ajax in a Promise
Secondly, .then takes two callback arguments, onfullfilled and onrejected, both of these callbacks only receive a single argument - your onrejected callback will never have status and error arguments - so that code is flawed
In the onfullfilled callback, the argument is an array, being the [result, status, jqXHR] that you would get in the $.ajax success call
Similarly, in the onrejected callback, the argument is an array, being [jqXHR, status, errorThrown]
Given all that, the authenticate function can be written
authenticate: function(options) {
return $.ajax({
url: this.tokenEndpoint,
type: 'POST',
headers: {'Content-Type': 'application/json', 'Accept-Encoding': 'gzip, deflate'},
data: JSON.stringify({
username: options.identification,
password: options.password
})
})
.then(function(arr) {
var response = arr[0];
console.log(response);
// return instead of resolve
return({
lastLoginDate: response.lastLoginDate,
login: response.login,
name: response.name,
role: response.role,
token: response.id_token
});
}, function(arr) {
var xhr = arr[0], status = arr[1], error = arr[2];
if(error !== undefined) {
console.log(error);
}
var response = xhr.responseText;
// return a rejection - could "throw response" instead
return Promise.reject(response);
}
);
}
and FYI - ES2015+ you could write
.then(function([response, status, xhr]) {
.....
}, function([xhr, status, error]) {
....