How to delay http responses on errors in Angular 7 - angular7

I am working on an Angular7 project and have some issues about error handling on http requests.
Here is my Login Component with two functions
export class LoginComponent implements OnInit, OnDestroy {
emailLogin1() {
this.authService.emailLogin1(this.loginForm.value).pipe(delay(1000)).subscribe(
(response) => {
console.log(response);
},
(error) => {
console.log(error);
}
);
}
emailLogin2() {
this.authService.emailLogin2(this.loginForm.value).pipe(delay(1000)).subscribe(
(response) => {
console.log(response);
},
(error) => {
console.log(error);
}
);
}
}
Here is my AuthService with two functions.
export class AuthService {
constructor(private http: HttpClient) {
}
emailLogin1(values): any {
return this.http.post(environment.server + '/auth/emailLogin', values).pipe(
tap(
(response) => {
localStorage.setItem('token', response['token']);
},
(error) => {
console.log(error);
}
)
);
}
emailLogin2(values): any {
return this.http.post(environment.server + '/auth/emailLogin', values).pipe(
tap(
(response) => {
localStorage.setItem('token', response['token']);
}
),
catchError((error) => {
console.log(error);
throw error;
})
);
}
}
When I make a request to the server, if response status is successful, it waits for 1000 ms and then shows the result as expected. But if response returns an error, delay(1000) function not working and error block working immediately. I tried with and without catchError. Both working exactly the same.

The delay operator will only work on events sent through the observable via "next" notifications (in your case, this is a "success"). When an error occurs, it is sent as an "error" notification, and it skips right past your delay operator. If you want to delay the error, you should catch it, introduce a delay, and then re-throw it:
emailLogin1() {
this.authService.emailLogin1(this.loginForm.value).pipe(
delay(1000), // only affects "success"
catchError(error => interval(1000).pipe( // only affects "error"
mergeMap(() => throwError(error)) // re-throw error after our delay
)),
).subscribe(
(response) => {
console.log(response);
},
(error) => {
console.log(error);
}
)
}

Related

Microsoft Graph on-behalf-of token - is it one-use only?

I'm able to retrieve an on_behalf_of token from my backend API to use client-side in my page, but if I make two calls to the Microsoft Graph, one immediately after the other, the second one always fails with a 401 unauthorized. The calls are one straight after the other, so definitely within the expiry time window. Is this token one-use only (i.e. it's invalidated straight after use), or am I doing something wrong?
My code is based on this sample, but I've extended it to make another call immediately to the Graph again, as follows:
function useServerSideTokenAgain(token) {
display("4. Call https://graph.microsoft.com/v1.0/me/messages with the server side token");
return fetch("https://graph.microsoft.com/v1.0/me/messages?$select=sender,subject",
{
method: 'GET',
headers: {
"accept": "application/json",
"authorization": "bearer " + token
},
mode: 'cors',
cache: 'default'
})
.then((response) => {
if (response.ok) {
return response.json();
} else {
throw (`Error ${response.status}: ${response.statusText}`);
}
})
.then((profile) => {
display(JSON.stringify(profile, undefined, 4), 'pre');
});
}
then later on, I've changed from the original code:
getClientSideToken()
.then((clientSideToken) => {
return getServerSideToken(clientSideToken);
})
.then((serverSideToken) => {
return useServerSideToken(serverSideToken);
})
.catch((error) => {
...
to this:
getClientSideToken()
.then((clientSideToken) => {
return getServerSideToken(clientSideToken);
})
.then((serverSideToken) => {
return useServerSideToken(serverSideToken);
})
.then((serverSideToken) => {
return useServerSideTokenAgain(serverSideToken);
})
.catch((error) => {
...
My app has delegated "Mail.Read" rights, so the operation itself works fine. Incidentally, if I change the order of operations, the same thing happens in reverse (step 4 works fine, but step 3 throws a 401 unauthorized):
getClientSideToken()
...
.then((serverSideToken) => {
return useServerSideTokenAgain(serverSideToken);
})
.then((serverSideToken) => {
return useServerSideToken(serverSideToken);
})
.catch((error) => {
...

FetchEvent.respondWith received an error: Returned response is null

I created a pwa site which is working totally fine in android devices both online and offline. But it is throwing error FetchEvent.respondWith received an error: Returned response is null when tried to load on IOS device with safari 13.0 if the mobile device is offline.
Here is my code snippet from service_worker.js
// install event
self.addEventListener('install', evt => {
evt.waitUntil(
caches.open(staticCacheName).then((cache) => {
return cache.addAll(assets);
})
);
});
// activate event
self.addEventListener('activate', (e) => {
e.waitUntil(
caches.keys().then((keyList) => {
return Promise.all(keyList.map((key) => {
if(key !== staticCacheName) {
return caches.delete(key);
}
}));
})
);
});
//fetch event
self.addEventListener('fetch', function(event) {
event.respondWith(
fetch(event.request).catch(function() {
return caches.match(event.request,{ignoreSearch: true});
})
);
});
Please, help me find the solution.

sendbird error 400 bad request /user not found

I am trying to play with sendbird. I am getting this error . I am trying to make sendbird api work in react.js app. I have read the documentation and it wasnt clear to me. I have looked at stackoverflow earlier replies and Thats why , i tried to create channel after i get connected to sendbird.
VM2257:1 POST https://api.sendbird.com/v3/group_channels 400 (BAD
REQUEST)
error is here p {name: "SendBirdException", code: 400201, message: "User not found."}
I am trying to implement it in react.js . Here's my code. Can someone help me out with how to rectify this error.
import React, { Component } from 'react';
import * as SendBird from 'sendbird';
import './App.css';
var sb = new SendBird({'appId': '59BEEA34-BDC7-461B-B10B-63705C8B57C2'});
class App extends Component {
componentWillMount(){
sb.connect("ankur1", function(user, error) {
if(user){
console.log("looks like connected",user)
var userIds = ['unique_user_id1', 'unique_user_id2','ankur1'];
var name = "amazing1";
sb.GroupChannel.createChannelWithUserIds(userIds, false, name, function(createdChannel, error) {
if (error) {
console.error("error is here",error);
return;
}
console.log("success",createdChannel);
});
}
else{
console.log("looks like error")
}
})
}
sm(){
console.log("button clicked",sb)
var channel = "amazing"
/*
sb.channel.sendUserMessage("that is cool", '', function(message, error){
if (error) {
console.error(error);
return;
}
console.log(message);
});
*/
}
componentDidMount(){
}
render() {
var sm = this.sm.bind(this)
return (
<div>
<h1>ankur is here </h1>
<button onClick={sm}>click here</button>
</div>
);
}
}
export default App;
I actually had a similar problem yesterday. Googling around it actually led me here. Eventually, I found a way around it.
So, the first thing I do after creating the connection to SendBird is to create a connection for that user I wish to connect to.
var sb = new SendBird({
appId: 'YOUR SENDBIRD APP ID HERE'
});
sb.connect(UNIQUE_USER_ID, function(user, error) {
connectToUser();
});
function connectToUser(){
sb.connect(YOUR_OWN_USERID, function(user, error) {
sb.GroupChannel.createChannelWithUserIds([UNIQUE_USER_ID], true, UNIQUE_USER_ID+YOUR_OWN_USERID, '', '', '', function(createdChannel, error){
$scope.chatChannel = createdChannel;
if (error) {
console.log(error);
return;
}
});
});
}
Then, you can proceed to send your messages using the createdChannel
$scope.chatChannel.sendUserMessage(YOUR_MESSAGE_HERE, '', '', function(message, error){
if (error) {
console.error(error);
return;
}
console.log(message);
});
Let me know if that works.

React Native IOS App crashes when no network conection

On the simulator it does not crash and Alerts the error, but in production it is crashes as soon as fetch request suppose to be made and it is impossible to reopen the app until network connection is back (I turn on/off airplane mode for the testing)
here are the snippets of my code
componentWillMount: function(){
NetInfo.isConnected.addEventListener('change',this.handleConnectivityChange)
NetInfo.isConnected.fetch().done((data) => {
this.setState({
isConnected: data
})
console.log('this.state.isConnected: ', this.state.isConnected);
})
},
handleConnectivityChange: function(){
var connected = this.state.isConnected ? false : true
this.setState({isConnected: connected})
console.log('this.state.isConnected11: ', this.state.isConnected);
},
....
goToList: function(replace, listview){
console.log('this.state.isConnected: ', this.props.isConnected);
if (!this.props.isConnected){
AlertIOS.alert('Error', 'Please check your network connectivity')
this.props.removeFetching()
return
}
....
fetch(url)
.then((response) => response.json())
.then((responseData) => {
....
.catch((error) => {
StatusBarIOS.setNetworkActivityIndicatorVisible(false)
AlertIOS.alert('Error', 'Please check your network connectivity')
this.props.removeFetching()
})
.done()
I spent a lot of time trying to find a way to catch exceptions when using fetch() but I was unable to get it working (e.g. using .catch() or a try/catch blog didn't work). What did work was to use XMLHttpRequest with a try/catch blog instead of fetch(). Here's an example I based off of: https://facebook.github.io/react-native/docs/network.html#using-other-networking-libraries
var request = new XMLHttpRequest();
request.onreadystatechange = (e) => {
if (request.readyState !== 4) {
return;
}
if (request.status === 200) {
console.log('success', request.responseText);
var responseJson = JSON.parse(request.responseText);
// *use responseJson here*
} else {
console.warn('error');
}
};
try {
request.open('GET', 'https://www.example.org/api/something');
request.send();
} catch (error) {
console.error(error);
}

Handing errors i.e., 401, 403, etc. for Ember Test

Searching for suggestions on handling errors in an Ember test? Found a closed issue from last year, Allowing rejected promises in tests, which indicated that rejections cannot be conveniently handled. Is this still the case?
Right now, in our application, we are using ajax errors to return an unauthorized error if the user is logged out of our main Rails application.
Route
import Ember from 'ember';
import {isUnauthorizedError, isForbiddenError} from 'ember-ajax/errors';
export default Ember.Route.extend({
userService: Ember.inject.service('user'),
activate: function(){
this.get('userService').facility().then(
(data) => {
this.get('controller').set('facility', data.data);
}, (response) => {
if (isUnauthorizedError(response)) {
this.transitionTo('report.failure.401');
} else if (isForbiddenError(response)) {
this.transitionTo('report.failure.403');
} else {
}
}
),
Acceptance Test
test('generates 401 error', function(assert) {
visit('/reporting');
httpStubs.stubUser(server, {}, 401);
httpStubs.stubFacility(server, {});
httpStubs.stubReport(server, '/api/reports/summary.json', []);
click('button.btn-filter')
andThen(function(){
assert.equal(currentURL(), '/users/login');
});
Report Stub
stubReport(server, url, data, status) {
let statusCode = (status) ? status : 200;
server.get(url, function() {
return [
statusCode,
{'Content-Type': 'application/json'},
JSON.stringify(data)
];
});
}

Resources