I'm new to RxJs and Angular2, and I'm trying to properly handle errors. I've seen some examples with Observables that have onNext, onError and onCompleted events (e.g. here, but all of the Angular2 http examples that I see seem to just use .catch and .map methods, and I'm not sure how that relates to the OnNext/OnError/OnCompleted model. I'm working with the code from here):
let stream = this.http.request(options.url, options)
.catch(error: any) => {
this.errorsSubject.next(error);
return Observable.throw(error);
})
.map(this.unwrapHttpValue)
.catch((error: any) => {
return Observable.throw(this.unwrapHttpError(error));
});
I initially wanted to just make it so that the first .catch and the .map are either/or? (i.e. the .map only runs if the http request is successful), but I'm not sure if that's even possible, and then it was further complicated by my reading the post here where it seems like they may be saying that per this fix, the map method will automatically be skipped if the HTTP code is <200 or >300...? However, that isn't what I'm observing in practice with angular 2.0.0-rc.4...
Many thanks for any assistance!
Think of catch being like typical try and catch code. For an observable, all of the operations will be run in order as if they were in a try block. If there is an error, then processing will jump down to the first catch.
So, if you only want to run the map on success, then you just put it before the catch:
let stream = this.http.request(options.url, options)
.map(this.unwrapHttpValue)
.catch(error: any) => {
this.errorsSubject.next(error);
return Observable.throw(error);
});
Related
I have an API automation test suite using Cypress and one of the issue I am facing in one of the test is to validate the response headers.
For some reason, I am not able to read the response headers using Cypress.
The code is below
cy.request({
method:'GET',
url:Cypress.env("Authorisationurl")+tokenId+'&decision=allow&acr_values=1',
followRedirect: false,
headers:{
'Accept': "/*"
}
}).then((response) => {
const rbody = (response.body);
cy.log(response.status)
//THIS GOT ASSERTED TO TRUE
expect(response.status).to.equal(302)
//OPTION1
cy.wrap(response.headers['X-Frame-Options']).then(() => {
return response.headers['X-Frame-Options'];
});
//OPTION2
return response.headers['X-Frame-Options']
//OPTION3
return response.headers
})
None of the above options gives me the header information. Infact I am confused with the order of execution too.
This is my output.
for the following code.
const rbody = (response.body);
cy.log(response.status)
cy.log(response)
expect(response.status).to.equal(302)
cy.log(response.headers)
cy.log(response.headers['X-Frame-Options'])
return response.headers['X-Frame-Options']
Also, not very sure what Object{9} indicates. Can anyone please explain what is happening here.
I am aware of Cypress flow of execution and the code is written in then block as a call back function.
Option 3 is very scary as it gives an error
cy.then() failed because you are mixing up async and sync code.
In your callback function you invoked 1 or more cy commands but then returned a synchronous value.
Cypress commands are asynchronous and it doesn't make sense to queue cy commands and yet return a synchronous value.
You likely forgot to properly chain the cy commands using another cy.then().
The value you synchronously returned was: Object{9}
Can anyone please help me here as in what is the correct way of doing it. I know Cypress is very quick and easy to use but to move away from Selenium, we need to make coding easier for developers with meaningful error message. Object{9} is not very helpful.
Also, Do I need to use Cy.log ? As the sequence of prints is not what I have written in the code. Thanks very much for your time on this.
Please use like this:
JSON.parse(JSON.stringify(response.headers))["X-Frame-Options"];
The "mixing async and sync code" message is basically saying you should keep the .then() callback simple.
But you can chain more than one .then() to run the async and sync code separately.
Use an alias to "return" the value. Since cy.request() is asynchronous, you will need to wait for the value and the alias pattern is the most straight-forward way to do this reliably.
WRT Object{9}, it's the result of the way Cypress logs complex objects.
Don't use cy.log() to debug things, use console.log().
cy.request( ... )
.then(response => {
expect(response.status).to.equal(200) // assert some properties
})
.then(response => response.headers) // convert response to response.headers
.as('headers')
cy.get('#headers')
.then(headers => {
console.log(headers)
})
Since this was originally posted a year ago and Cypress has had many versions since then, the behavior may have changed, however this works in Cypress 11.
You can access the response.headers array as you would normally expect, however the casing of the header name was not as expected, Postman reported the header as X-Frame-Options, but Cypress would only allow me to access it if I used a lower-cased version of the header name (x-frame-options).
cy.request({
url: '<Url>',
method: 'GET',
failOnStatusCode: false
})
.then((response) => {
expect(response.status).to.eq(200);
expect(response.headers["x-frame-options"]).to.equal("SameOrigin");
})
.its('body')
.then((response) => {
// Add your response testing here
});
});
I'm having problem to make my Action resolve the promise.
I've read what looks like the most relevant posts.
Returning Promises from Vuex actions
I want to know when my action is finished, then my component can start doing other stuff.
The problem is, the Action never returns the Promise.
myComponent.vue
methods: {
loadUrls() {
this.$store.dispatch('getUrls').then(result => {
console.log("getUrls result", result)
})
},
vuex.js
actions: {
getUrls() {
console.log("getUrls")
return new Promise((resolve) => {
setTimeout(() => {
console.log("setTimeout in")
resolve("Resolved!")
}, 1000)
})
},
That's my console log:
I've used the "setTimeout" to make as simple as possible the problem. In real life I call an API.
I do not need to rely on the result of this promise. I'm aware about it. I use Vuex as the source of truth, but I need to track when the event in completed.
Thanks in advance =)
SOLVED! It worked after I delete my dist Folder, close VSCode and open a new Chrome instance using the new build local host URL.
Thanks #User-28. I saw his shared code and realised nothing was wrong with my code. Then I start looking at my environment.
My very first code didn't have Promise Resolve in the action. I compiled and I was testing it.
Then I found Returning Promises from Vuex actions which explained how to use the Promise in it. I compiled and I was TRYING to test it. Never success. Somehow the code without the Promise was always there. After clean up Dist folder, Close VS code and use a new Chrome instance, the new code was in place and worked.
I'm still don't know the actual problem, but at least it can keep going forward now.
async No response On the server side, 200ok comes in, but I can't get it.
I've tried the watch method, but don't. I want to solve it asynchronously.
async mounted() {
try{
let response =await axios.get('http://localhost:5000/process')
this.msg = response
}
catch (err) {
// eslint-disable-next-line
console.log(err)
}
}
};
There is no reaction.
An axios response will contain a number of properties what you are likely looking for is response.data try that and you should have your response assuming you are actually getting something. You can always look in the network tab to see exactly what is coming in even if it not showing on your app, just look for the call and see what the response or preview show.
In the event that your data is not updating in the template you would need to create a key on the element that needs to update to force a rerender, this is because vue's reactivity only works (or mostly) with primitive values not nested structures.
I'm learning React Native and I was looking up how to make a promise chain with an API call as referenced here: https://facebook.github.io/react-native/docs/network.html#handling-the-response.
In looking how to get user permissions, I looked at the docs page for it (https://facebook.github.io/react-native/docs/permissionsandroid.html) and wondered if the promise concept could be applied here to make it a little
My main question is this: How does promises improve functionality (if at all) and what is the best way to adapt code to use promises?
Here is some other code that I would use for easy reference:
async requestLocationPermission() {
const chckLocationPermission = PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION);
if (chckLocationPermission === PermissionsAndroid.RESULTS.GRANTED) {
console.log("You've access for the location");
} else {
try {
const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
'title': 'This App required Location permission',
'message': 'We required Location permission in order to get device location ' +
'Please grant us.'
}
)
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log("You've access for the location");
} else {
console.log("You don't have access for the location");
}
} catch (err) {
console.log(err)
}
}
};
The short answer is yes.
If you need the data from your API request, then you need to use promises.
For more on why you would need to use a promise, you want to learn about more about the call stack.
I think there's a small confusion (which is pretty common), but the code you linked is also using promises.
Async/Await is a new JavaScript feature that makes writing promises easier.
There are a more than a few ways you can write promises in JavaScript e.g. Fetch, Promise, Async/Await. Not to mention libraries like AngularJS have their own implementation of this.
I'd recommend to study up on the Call Stack first and then go from there.
Simply:
You are writing much cleaner code with async await rather than then() catch() etc. methods
If you have other programming language knowledge probably you miss try/catch blocks. It allows you write sync & async methods in same block.
Personal recommendation you should be familiar with callbacks => promises => generators => async await (learn in order). It's actually your decision to use which one best fits for your purposes. I'd suggest to look very detailed guide about these topics (he actually wrote a book for just these topics xd) You Don't Know JS: Async & Performance
I am running redux on node. To handle asynchronous actions, like reading a file or listing of a directory, I am using redux-thunk in combination with Promises. So a typical action can look like that:
const
fs = require('fs'),
{ promisify } = require('util'),
readdir = promisify(fs.readdir);
const listFiles = dir => dispatch =>
readdir(dir)
.then(files => dispatch({
type: '…',
payload: { files }
}));
So:
try {
store.dispatch(listFiles('/some/path'));
catch (error) {
//some rescue plan here,
//won't work if directory not exists
}
wont work here, because the action is asynchronous and right now, the only way I see to handle all errors is to add a .catch() to all promises in all actions and dispatch an error action there.
That has two downsides:
a lot of code repetition and
i need to know all possible errors in ahead.
So my question is: Is there any way to create a global error handler, which will also be called if an asynchronous action fails, such that I can add some error indicating information to the state, which can be displayed?
Could that be possible with a »storeEnhancer« or some »middleware«?
UPDATE
I could find something that is really helpful:
process.on('unhandledRejection', (reason, promise) => {
console.log(reason.message);
});
That callback is triggered whenever a Promise is rejected and no catch block is added. Right now that seams to do the trick, but anyway, I would prefer a solution that basically does the exact same thing, but only for rejected Promises which are triggered within store.dispatch(), so only when an error within the processing of actions/middleware/reducers within redux comes to happen.
If you're looking for a redux middleware solution, take a look at redux-catch.