http.get don't make a call, Angular 2 - http

I am playing with angular 2 and I have problem with sending http get request.
I created method like this:
test(){
console.log("call test");
let header = new Headers();
header.append("authorization",'change9ziKuJH8wnVbNES3AMleYGPKzZ');
this._http.get('http://localhost:42055/api/Question',{headers:header}).do(res => console.log("Result: " + JSON.stringify(res)));
}
The main problem is that, this http request never was send. I look at the Fiddler and there is no request to my localhost:42055.
Unfortunately Angular don't display any errors, so I don't have any clue what is going one.

Observables are lazy so you need to subscribe them to actually execute corresponding processing (HTTP requests in your case):
this._http.get('http://localhost:42055/api/Question',{headers:header})
.do(res => console.log("Result: " + JSON.stringify(res)))
.subscribe((res) => { // <-------------
// handle result
});

Related

Cypress: How to access the body of a POST-request?

Is there a way in Cypress to check the body of a POST-request?
E.g.: I have entered some data in a form, then pressed "Submit".
The form-data is send via POST-request, separated by a blank line from the header-data.
I would like to check the form-data. If all data, which I have entered, are included and if they are correct.
Is that possible with Cypress?
cy.get('#login').then(function (xhr) {
const body = xhr.requestBody;
console.log(xhr);
expect(xhr.method).to.eq('POST');
});
The xhr-object doesn't have the transferred data included.
It should be possible.
describe('Capturing data sent by the form via POST method', () => {
before(() => {
Cypress.config('baseUrl', 'https://www.reddit.com');
cy.server();
cy.route({
method: 'POST',
url: '/login'
}).as('redditLogin');
});
it('should capture the login and password', () => {
cy.visit('/login');
cy.get('#loginUsername').type('username');
cy.get('#loginPassword').type('password');
cy.get('button[type="submit"]').click();
cy.wait('#redditLogin').then(xhr => {
cy.log(xhr.responseBody);
cy.log(xhr.requestBody);
expect(xhr.method).to.eq('POST');
})
});
});
This is how you can inspect your data in Chrome Developer Tool.
You should see the same thing you've seen from Chrome Developer Tool when you run your test in Cypress.
I was Googling the same problem and somehow landed here before reaching the documentation.
Anyway, have you tried something like:
cy.wait('#login').should((xhr) => {
const body = xhr.request.body
expect(body).to.match(/email/)
})
I haven't tested it out with a multipart/form-data encoded request, but I suspect that you'll also find the request body that way.
Good luck!
It's better to use cy.intercept() in order to spy, stub and assert network requests and responses.
// assert that a request to this route
// was made with a body that included 'user'
cy.wait('#someRoute').its('request.body').should('include', 'user')
// assert that a request to this route
// received a response with HTTP status 500
cy.wait('#someRoute').its('response.statusCode').should('eq', 500)
// assert that a request to this route
// received a response body that includes 'id'
cy.wait('#someRoute').its('response.body').should('include', 'id')
Link to the docs

angular5 how to make asyc request?

In my project i made multiple request to server to get data for single page. I want to make all request asyc. Right now until i get the response from first request,the response of second request is not load.
So basically i just want to achive asyc request and response so one request will not wait for other request to finish.
Right now it's like first come first serve fashion.
But i want from multiple request which request get first response should load first.
this is code of my component
constructor(private _dashboardService: DashboardService) {
this.getLineChart();
this.todayPaymentDetails();
this.todayPaymentMethod();
this.rewardCustomers();
this.getAverageBill();
this.getItemByVolumn();
this.getItemBySales();
}
todayPaymentMethod(id=null){
this.paymentMethodsLoader=0;
this._dashboardService.getTodayPaymentMethod(id).subscribe(res =>{
if(null != res.data && '' != res.data){
this.location = res.data.location;
this.payment_methods = res.data.payment_methods;
}
this.paymentMethodsLoader=1;
});
}
this is my service code:
getTodayTotalPayment(id) : Observable<any> {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this._http.get(environment.apiUrl + constants.API_V1 + 'today-total-payment/'+id, options)
.map(res => res.json())
.catch((error: any) => Observable.throw(error.json().error || error));
}
Here shows code for only one request but as shown in constructor i send multiple request at a time.
FIrst it is not a good practise to call function like this in constructor.
For running multiple request or observable together use operators i.e. switchMap etc.
Follow this video link related to event loop in JavaScript this will improve your JavaScript execution , event loop concepts . also explains how asynchronous code executed.
Hope it will help.

Koa SSE connection reconnecting

I have set up an SSE connection using Koa like so:
const Koa = require('koa');
const Router = require('koa-router');
const app = new Koa();
const router = new Router();
// Sets up the HTTP header and sends a message via SSE
function writeSSE(ctx, message) {
ctx.res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
'Access-Control-Allow-Origin': '*',
});
ctx.res.write(`id: 01\n`);
ctx.res.write(`data: ${message}\n\n`);
}
// Router Middleware
router.get('/stream', (ctx, next) => {
writeSSE(ctx, 'Stream reached.');
});
app.use(router.routes()).use(router.allowedMethods());
app.listen(8080);
Where my React components starts the connection like so:
new EventSource("http://localhost:8080/stream")
The component then receives the answer sent by the writeSSE method on the backend.
But for some reason the /stream endpoint is reached every 3 seconds or so, as if the connection was being reestablished.
And my error listener on the front-end catches a CONNECTING event every time.
this.state.source.onerror = (e) => {
if (e.target.readyState == EventSource.CONNECTING) {
console.log("Connecting...");
}
};
And on the back-end, ctx.response equals { status: 404, message: 'Not Found', header: {} }.
Would anyone know the cause of this issue? Is it linked to the way I use Koa?
this is a bit too late, but I will write my experience with sse using Koa.
First of all using ctx.res directly is not much appreciated by Koa, if you still want to use it make sure to put ctx.respond = false to bypass koa response mecanism.
In my experience a stream is the best way to use SSE with Koa you can do something like :
const stream = require('stream');
const koa = require('koa');
const app = new koa();
app.use(async ctx => {
ctx.set({
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
ctx.status = 200;
const stream = new stream.PassThrough()
ctx.body = stream; // here koa will pipe the ctx.res to stream and end the ctx.res when ever the stream ends.
let counter = 5;
const t = setInterval(() => {
stream.write(`data: hi from koa sse ${counter}`);
counter--;
if (counter === 0) {
stream.end();
clearInterval(t);
}
}, 1000);
});
Hope this help anyone will play with SSE on koa.
PS: I wrote this on hurry if there is anything wrong with code tell me and I will correct it.
I'm in the process of implementing a Koa-based server for SSE. I've been running into the same problem, and here are my thoughts / working solution:
As far as I can tell, the reason why onmessage and onerror keep getting called is because the EventSource object on the client side is emitting an error event. This is causing the connection to be disconnected, which causes the client to send another request to initialize the stream to the server. From here, the process repeats itself indefinitely.
Based on my own testing, EventSource is emitting an error due to the data that is being sent back from the server. Per the docs, a 200 response that has as Content-Type other than 'text/event-stream' will cause a failure.
In your example, you have declared your response as 'text/event-stream' and are passing a string into the ctx.res.write method. While this looks correct, and in fact works when using comparable code and Express, it seems that it doesn't work in Koa. However, if you change the 'data' you are writing to your response to a stream, such as this example here, you'll find that the connection establishes correctly.
Maybe try the following:
//require Passthrough
const PassThrough = require('stream').PassThrough;
//then, in your writeSSE function, try this:
let stream = new PassThrough();
stream.write(`data: ${message}\n\n`);
ctx.res.write(stream);
I'm not 100% sure why this change works. My best guess is that there is something about Koa's ctx object that prevents a plain string or template literal from being viewed as valid text/event-stream data, but this is entirely supposition (this begs the question as to why it works in Express, but hopefully someone more knowledgeable can answer this for both of us). From what I've seen of other snippets published online, the stream approach is the one to take in Koa.
I'm not sure what your results will be, as it looks like you may be using a different version of Koa than I am, but I'd give it a shot. I was able to get my connection established correctly making this small change.

Angular2 display .NET API validation messages

I am transacting .NET API through Angular2(honestly.. 5) I implement server side-model validation using Data Annotations Attributes. As such, the API returns bad request(404) with the validation messages attached:
if (!ModelState.IsValid)
return this.BadRequest(ModelState);
My issue has to do on how to display those messages in my angular view.
My Angular service:
submitForm(formObj: FormDto) {
let headers = new HttpHeaders();
headers = headers.append('Content-Type', 'application/json; charset=utf-8');
return this.http.post("/api/Forms", JSON.stringify(formObj), { headers })
.map((res: Response) => console.log(res));
//need a .catch here obviously ??????
}
and the way I call the service from the component itself:
submitForm() {
this.formService.submitForm(this.formObj)
.subscribe(res => { console.log(res);
//update this bit to display error messages ?????
});
}
Again, my issue is how to display properly the returned validation error messages coming from the .NET API.
Let's star with the fact that the modelState is coming as an object(key-value pairs). Thus, you can access the object in view by a specific key. You can have a variable in your component and store the modelState object in it.
To the point....
I wouldn't touch the Angular service at all, but the way you subscribe to it in order to separate success and failed callback:
submitForm() {
this.formService.submitForm(this.formObj)
.subscribe((data) => //do what ever on success,
(err) => { this.errors= err.error; });
}
After that, you are able to see your error messages in the view. Something like:
<span class="error-message">{{errors['EmailAddress']}}</span>
Put the line above to every input it's needed but change the key to view the right message. I've done a quick demo and is working.
I hope that helped.

Is there a way to be notified when a client has unsubscribe from server sent events?

As I understand when a request to an event emitter on the server arrives, that request is never closed and you only need to res.write() every time you would like to send a message. However is there a way to be notified when the client that performed this request has left? Is there a property on the request object?
suppose I have the following route
app.get('/event',function(req,res){
//set response headers
//how do I check if req object is still active to send a message and perform other actions?
})
The basic sequence of events should be similar in other frameworks, but this example is Grails 3.3.
First set up endpoints to subscribe, and to close the connection.
def index() {
// handler for GET /api/subscribe
rx.stream { Observer observer ->
// This is the Grails event bus. background tasks,
// services and other controllers can post these
// events, CLIENT_HANGUP, SEND_MSG, which are
// just string constants.
eventBus.subscribe(CLIENT_HANGUP) {String msg ->
// Code to handle when the grails event bus
// posts CLIENT_HANGUP
// Do any side effects here, like update your counter
// Close the SSE connection
observer.onCompleted()
return
}
eventBus.subscribe(SEND_MSG) {String msg ->
// Send a Server Sent Event
observer.onNext(rx.respond(msg))
}
}
}
def disconnecting()
{
// handler for GET /api/disconnect
// Post the CLIENT_HANGUP event to the Grails event bus
notify(CLIENT_HANGUP, 'disconnect')
}
Now in the client, you need to arrange to GET /api/disconnect whenever your use-case requires it. Assuming you want to notice when someone navigates away from your page, you could register a function on window.onbeforeunload. This example is using Vue.js and Axios.
window.onbeforeunload = function (e) {
e.preventDefault()
Vue.$http({
method: 'get',
url: 'http://localhost:8080/api/disconnect'
})
.then((response) => { console.log(response) })
.catch(({error}) => { console.log(error) })
}
In the case of Servlet stacks like Grails, I found that I needed to do this even if I had no housekeeping of my own to do when the browser went away. Without it, page reloads were causing IOExceptions on the back end.

Resources