Observable not firing during Angular 2 HTTP request - ajax

I have the following method, using Ionic 2 with Angular 2:
private login(params: any, url: string){
var p = new Promise<JsonResult>((resolve, reject) => {
let body = JSON.stringify(params);
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
this.http.post(url, body, options)
.timeout(10000, new Error('Timeout exceeded during login'))
.subscribe((res) => {
let json = new JsonResult().deserialize(res.json());
resolve(json);
}, (err) => {
reject(err);
});
});
return p;
}
No matter what I do, the subscribe is not working as expected.
The error handler never gets fired. Not even after the timeout has exceeded.
Is this a known problem, or is there something wrong with my syntax?
Any help would be appreciated.

If you want to return a Promise I would do it this way:
private login(params: any, url: string){
let body = JSON.stringify(params);
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(url, body, options)
.timeout(10000, new Error('Timeout exceeded during login'))
.catch(err => {
console.log(err);
return Observable.of([]));
})
.map((res) => {
return new JsonResult().deserialize(res.json());
})
.toPromise();
}

Related

Getting 429 (Too Many Request) in vue.js laravel

I'm using vue.js and laravel when i open edit page i get this error in my console but Update function is called on button click and bill url is also called multiple times without parameter on mounted function
app.js:1088 GET http://localhost:8000/api/userbackend/bill/undefined 404 (Not Found)
POST http://localhost:8000/api/userbackend/Update 429 (Too Many Requests)
Code Snippet:
async mounted(){
this.roleid = this.userData.role_id;
const header = {
'Authorization': 'Bearer ' + this.LoginUserData,
};
this.editId = this.$route.params.id;
if(this.$route.params.id !== undefined) {
try{
let response = await axios.get(`/api/userbackend/bill/${this.editId}` ,{headers: header});
this.form = response.data;
}
saveRecord(){
let loader = this.$loading.show();
let formData = new FormData();
formData.append('id', this.editId);
....
const header = {
'Content-Type': 'multipart/form-data',
'Authorization': 'Bearer ' + this.LoginUserData,
};
axios.post('/api/userbackend/Update', formData ,{headers: header}).then((response) =>{
loader.hide();
if(response.data.status == true){
.....
}
})
.catch((response) => {
loader.hide();
this.showErrorMsg();
});
},
validateBeforeSubmit(e) {
e.preventDefault();
let app = this;
this.$validator.validateAll().then((result) => {
if (result) {
app.saveRecord();
return;
}
this.showWarningMsg();
});
}
Any suggestion is highly appreciated

Network Request failed while sending image to server with react native

i want to send image to a server and getting the result with a json format but the application returns a Network Request failed error
react native 0.6 using genymotion as emulator
i tried RNFetchblob but the result take a long time to get response (5 min )
also i tried axios but it response with empty data with 200 ok
this is the function that import the image
OnClick = () => {
ImagePicker.showImagePicker(options, response => {
console.log("Response = ", response);
if (response.didCancel) {
console.log("User cancelled image picker");
} else if (response.error) {
console.log("Image Picker Error: ", response.error);
} else {
let source = { uri: response.uri };
// You can also display the image using data:
//let source = { uri: 'data:image/jpeg;base64,' + response.data };
this.setState({
avatarSource: source,
data: response.data,
BtnDisabled: false
});
console.log();
}
});
};
and this method that sends the image
Send = async () => {
let url = "http://web001.XXX.com:8000/api/prediction/check_prediction/";
let UplodedFile = new FormData();
UplodedFile.append('file',{ type:'image/jpeg', uri : this.state.avatarSource , name:'file.jpeg'});
fetch(url, {
method: 'POST',
body:UplodedFile
})
.then(response => response.json())
.then(response => {
console.log("success");
console.log(response);
})
.catch(error => {
console.error(error);
});
i expect json format
ScreenShot here
can you change your code like this?
OnClick = () => {
ImagePicker.showImagePicker(options, response => {
console.log("Response = ", response);
if (response.didCancel) {
console.log("User cancelled image picker");
} else if (response.error) {
console.log("Image Picker Error: ", response.error);
} else {
let source = { uri: response.uri };
// You can also display the image using data:
//let source = { uri: 'data:image/jpeg;base64,' + response.data };
this.setState({
pickerResponse: response,
data: response.data,
BtnDisabled: false
});
console.log();
}
});
};
Send = async () => {
let url = "http://web001.XXX.com:8000/api/prediction/check_prediction/";
let UplodedFile = new FormData();
UplodedFile.append('file',{ type:'image/jpeg', uri : this.state.pickerResponse.path , name:'file.jpeg'});
axios({
method: "post",
url: url,
data: UplodedFile
})
.then(response => {
console.log("success");
console.log(response);
})
.catch(error => {
console.error(error);
});

Cypress - unable to store response.body data into a JSON file

I've created a POST XMLHttpRequest with FormData successfully. I now need to capture it's response body and get it stored in a JSON file.
Cypress.Commands.add(
"Post_Clients",
(imagePath, imageType, attr1, attr2, attr1Val, done) => {
cy.fixture(imagePath, "binary").then(imageBin => {
Cypress.Blob.binaryStringToBlob(imageBin, imageType).then(blob => {
const xhr = new XMLHttpRequest();
xhr.withCredentials = true;
const data = new FormData();
data.set(attr1, attr1Val);
data.set(attr2, blob);
xhr.open("POST", "https://api.teamapp.myhelpling.com/admin/clients");
xhr.responseType = "json"
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("access-token", accesstoken);
xhr.setRequestHeader("client", client);
xhr.setRequestHeader("expiry", expiry);
xhr.setRequestHeader("token-type", tokentype);
xhr.setRequestHeader("uid", uid);
xhr.onload = function() {
done(xhr);
};
xhr.onerror = function() {
done(xhr);
};
xhr.send(data);
});
});
}
);
it.only("API POSTing TEST", () => {
cy.Post_Clients(
"/images/clients/Golden JPEG.jpeg",
"image/jpeg",
"client[name]",
"client[client_logo_attributes][content]",
"Test Attr 1 Value is Hi!!!",
resp => {
cy.writeFile(
"cypress/fixtures/POST API OUTPUT DATA/Client.json",
resp.response
);
expect(response.status).to.eq(201);
}
);
});
Kindly note that expect(response.status).to.eq(201); assertion works well.
Following code logs the body properly in the console
cy.log("Response Body", resp.response);
console.log("Response Body", resp.response);
Response Body is: -
{"client":{"id":452,"name":"Test Attr 1 Value is Hi!!!","client_logo":{"id":543,"path":"https://api.teamapp.myhelpling.com/uploads/client_images/6279486665-1551780183.","thumb":"https://api.teamapp.myhelpling.com/uploads/client_images/thumb_6279486665-1551780183.","medium":"https://api.teamapp.myhelpling.com/uploads/client_images/medium_6279486665-1551780183.","large":"https://api.teamapp.myhelpling.com/uploads/client_images/medium_6279486665-1551780183.","filename":"blob","ratio":1.78}}}
but
cy.writeFile(
"cypress/fixtures/POST API OUTPUT DATA/Client.json",resp.response
);
doesn't save the response body in Client.JSON file.
cy.writeFile seems to not work in this code. I've verified this by
passing a JSON e.g. {"A":"B"} and that too didn't make it to the
JSON.
Thanks everyone for all you kind help. I've made it work by calling cy.writeFile inside onLoad event before triggering XHR request. Here's the code sample with some other updates that I've made for my other works: -
Cypress.Commands.add(
"Post_Bucket",
(imagePath, imageType, title, img, titleVal) => {
cy.fixture(imagePath, "binary").then(imageBin => {
Cypress.Blob.binaryStringToBlob(imageBin, imageType).then(blob => {
const xhr = new XMLHttpRequest();
const data = new FormData();
data.set(title, titleVal);
data.set(img, blob);
cy.readFile(Cypress.env("IDStore")).then(obj => {
xhr.open(
"POST",
Cypress.env("BucketPostURLPart1") +
obj.journeyID +
Cypress.env("BucketPostURLPart2"),
false
);
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("access-token", accesstoken);
xhr.setRequestHeader("client", client);
xhr.setRequestHeader("expiry", expiry);
xhr.setRequestHeader("token-type", tokentype);
xhr.setRequestHeader("uid", uid);
xhr.onload = function() {
if (this.status === 201) {
cy.writeFile(
Cypress.env("BucketOutputFile"),
JSON.parse(this.responseText)
);
cy.readFile(Cypress.env("IDStore")).then(obj => {
obj.bucketID = JSON.parse(this.responseText).bucket.id;
cy.writeFile(Cypress.env("IDStore"), obj);
});
}
};
xhr.send(data);
});
});
});
}
);
This is the simple example try with this one.
cy.request('https://jsonplaceholder.cypress.io/users')
.then((response) => {
cy.writeFile('cypress/fixtures/users.json', response.body)
})

react-native fetch with authorization header sometime return 401

I'm facing some issue whereby I sometime will get status code 401 (Unauthorised) from my phone. I'm trying to access to an API from my computer localhost (192.168.0.7).
I've a screen, when I click on a button it will navigate to a page and it will request data through API. And when I go back and navigate to same page again, it sometime will return me code 401.
So if I repeat the same step (navigate and go back) let's say 10 times. I'm getting Unauthorised like 5-7 times.
Below are my code
export function getMyCarpool(param,token) {
return dispatch => {
var requestUrl = _api + 'GetMyProduct?' + param;
fetch(requestUrl, {
method: "get",
headers: new Headers({
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + token
})
})
.then((request) => {
console.log(request);
if(request.status == 200)
return request.json();
else if(request.status == 401) {
//dispatch(logout());
throw new Error('Unauthorized access.');
}
else
throw new Error('Failed to request, please try again.');
})
.then((response) => {
var message = response.message;
if(response.success == 'true')
dispatch({ message, type: GET_MY_PRODUCT_SUCCESS });
else
dispatch({ message, type: GET_MY_PRODUCT_FAILED });
})
.catch(error => {
var message = error.message;
dispatch({ message, type: GET_MY_PRODUCT_FAILED });
});
}
I've check the token in my phone and also trying to make many request using postman. So I don't think it's server side problem.
I'm using Laravel and using laravel passport for API authentication. I not sure why this happen if I continue to access many time, any help is greatly appreciated.
UPDATE :: I'm trying to capture whether the http request has the token from this link, and I don't get the problem anymore.
It's a healthy mechanism for token expire. Maybe you have your token (access_token) for 5 minutes, then the token expired, you should use refresh_token to regain another new token (access_token).
For code explanation:
async function fetchService(url) {
const reqSetting = {
headers: {
Accept: 'application/json',
Authorization: `Bearer ${Auth.access_token}`,
},
};
const prevRequest = { url, reqSetting };
const resp = await fetch(url, reqSetting);
if (!resp.ok) {
const error = new Error(resp.statusText || 'Request Failed!');
if (resp.status === 401 || resp.status === 400) {
const responseClone = resp.clone();
const errorInfo = await resp.json();
if (errorInfo.error == 'invalid_token') {
// console.log('Token Expired', errorInfo);
try {
await refreshToken();
const response = await fetchService(prevRequest.url);
return response;
} catch (err) {
// handle why not refresh a new token
}
}
return responseClone;
}
error.errorUrl = url;
error.code = resp.status;
throw error;
}
return resp;
}
Where the refresh token function is :
async function refreshToken() {
const url = 'https://example.com/oauth/token';
const data = {
grant_type: 'refresh_token',
refresh_token: Auth.refresh_token,
};
try {
const res = await fetch(url, data);
const data = res.json();
Auth.access_token = data.access_token;
Auth.refresh_token = data.refresh_token;
return true;
} catch (error) {
throw error;
}
}
This fetchService will automatic regain a new token if old expired and then handle old request.
PS.
If you have multiple requests same time, the fetchService will need a little optimization. You'd better choose another regain token strategy like saga.

authClient is not called with the AUTH_ERROR

I'm trying to implement custom rest client build on top of simple fetch.
If 401-403 response received, it must "redirect" app to login page.
According documentation, if 401-403 error received, it will magically calls authClient with the AUTH_ERROR, but it doesn't.
Can someone explain, how to connect it?
I'm trying to call rest client from component: It's simple reimplementation of 'simpleRestClient'
componentDidMount() {
restClient(CREATE, 'api/method', {
CurrentTime: new Date()
})
.then(o =>
{
this.setState({ Msg: Object.values(o.data.ServerTime) });
});
}
restclient implementation:
export const fetchJson = (url, options = {}) => {
const requestHeaders =
options.headers ||
new Headers({
Accept: 'application/json',
});
if (
!requestHeaders.has('Content-Type') &&
!(options && options.body && options.body instanceof FormData)
) {
requestHeaders.set('Content-Type', 'application/json');
}
if (options.user && options.user.authenticated && options.user.token) {
requestHeaders.set('Authorization', options.user.token);
}
return fetch(url, { ...options, headers: requestHeaders })
.then(response =>
response.text().then(text => ({
status: response.status,
statusText: response.statusText,
headers: response.headers,
body: text,
}))
)
.then(({ status, statusText, headers, body }) => {
if (status < 200 || status >= 300) {
return Promise.reject(
new HttpError(
(json && json.message) || statusText,
status,
json
)
);
}
let json;
try {
json = JSON.parse(body);
} catch (e) {
// not json, no big deal
}
return { status, headers, body, json };
});
};
const httpClient = (url, options = {}) => {
if (!options.headers) {
options.headers = new Headers({ Accept: 'application/json' });
}
return fetchJson(url, options);
}
Have you tried rejecting the promise with an Error rather than an HttpError?

Resources