How to call chain subscription (RxJs) in ionic events - rxjs

I have a BaseDataService class and it has a method for HttpGet requests.
protected Get<TResponse>(
endPoint: string
): Observable<BaseResponse<TResponse>> {
return this.httpClient.get<TResponse>(this.baseUrl + endPoint).pipe(
map(data => {
const response = <BaseResponse<TResponse>>{};
response.Data = data;
response.Errors = [];
response.HasError = false;
return response;
}),
catchError(errors => {
const response = <BaseResponse<TResponse>>{};
response.Errors = [];
response.Errors.push(errors.error);
response.HasError = true;
return of(response);
})
);
}
And I have a LocationDeviceDataService which extends BaseDataService and it has a method for Get LocationDevices
getAll() {
return this.Get<BasePaginatedResponse<LocationDeviceResponse>>(
EndPoints.GET_LOCATIONDEVICES
);
}
And I am calling this method inside event ,
this.events.subscribe("connection-type:wifi", () => {
this.locationDataService.getAll().subscribe(t => {
localStorage.setItem('LOCATION_DEVICES', JSON.stringify(t.Data.items))
});
});
Everything is fine at first call , but when another events (https://ionicframework.com/docs/api/util/Events/)publish for "connection-type:wifi" this.locationDataService.getAll().subscribe returns responses 1x,2x,4x etc. slower.
I am sure for nothing wrong in back-end.
Should unsubscribe or complete subscription ? If I should , I dont have any trigger for that.
Could you please tell me what is wrong in this code ?

I solved my issue.
I think you can not call observable method inside Ionic events so I changed my method to void. Everything is fine for now.

Related

error Policy in Apollo Client React does'nt work

I have aproblem when test Apollo.When I try query with apollo and graphql, i want response return error and partical data, so I set property errorPolicy:'all'. But its not work. I don't no why? Help please!
Here my code:
query { animal {
name
age }, school {
name
numberfd } } `
const { loading,data,error} = useQuery(GET_DASHBOARD_DATA, {
errorPolicy:'all',
onCompleted: (res) => {console.log("complete",res)},
onError : (res,data) => {console.log("ERRRR",res,data)},
})
and i want to receive:
{
error:[...], data:[animal:[...]] }
but its only response error.Here is Apollo's doc: https://www.apollographql.com/docs/react/data/error-handling/
onError type is onError?: (error: ApolloError) => void;. You don't have data inside onError callback.
After useQuery you can add:
console.log('data', data)
console.log('error', error)
I faced the same issue with errorPolicy: 'all', I only received the partial result inside onCompleted callback of useQuery, but no errors.
I created an ErrorLink like this:
private createErrorLink = () => {
return new ApolloLink((operation, forward) => {
return forward(operation).map((response) => {
// filter out errors you don't want to display
const errors = filterSomeErrors(response.errors);
if (errors && response?.data) {
response.data.errors = errors;
}
return response;
});
});
};
Now inside my onCompleted callback I get my data as well as errors. You will have to tweak your types a bit, because seems there is no errors field on response.data by default.
Mind that if you use onError from Apollo and return something from the link, it will retry your request containing errors!

How to pass a parameter in Koa middleware?

So I have this function in Koa, that basically checks if a user can access a specific route.
exports.requireRole = async role =>
async (ctx, next) => {
const { user } = ctx.state.user;
try {
const foundUser = await User.findById(user.id);
// If the user couldn't be found, return an error
if (!foundUser) {
ctx.status = 404;
ctx.body = { errors: [{ error: ERRORS.USER_NOT_FOUND }] };
} else {
// Otherwise, continue checking role
if (getRole(user.role) >= getRole(role)) {
await next();
}
ctx.status = 403;
ctx.body = { errors: [{ error: ERRORS.NO_PERMISSION }] };
}
} catch (err) {
ctx.throw(500, err);
}
};
And I want to use it as a middleware:
router.delete('/:id', combine([jwtAuth, requireRole(ROLES.ADMIN)]), deleteUser);
But then I get an error saying:
middleware must be a function not object
This happens only when I try to pass an argument into it.
What am I doing wrong here?
The issue you are having is due to the fact that Promises are objects, and async functions return Promises. You need to change your initial function to be as follows:
exports.requireRole = role =>
instead of
exports.requireRole = async role =>
I was going over middleware myself, and ran into this issue as well.
Your middleware looks fine, what is combine?
Also, since you are using koa-router you don't need it.
router.delete('/:id', jwtAuth, requireRole(ROLES.ADMIN), deleteUser);

`RxJS` throws error on subcribe when do request

I am making a request using observable. and trying to subcribe the value. But getting error on typescript. any on help me?
I like to do this:
public getCountry(lat,lan):Observable<any>{
return this.http.get(this.googleApi+lat+','+lan+'&sensor=false').subscribe(data => {
return this.genertedData(data);
} );
}
But getting error as follows:
UPDATES
public getCountry(lat,lan):Observable<any>{
return this.http.get(this.googleApi+lat+','+lan+'&sensor=false').map( data => {
data.results.map( array => {
let details = array.address_components.find( obj => obj.types.includes("country") );
this.countryDetails.countryLongName = details.long_name;
this.countryDetails.countryShortName = details.short_name;
})
return this.countryDetails;
})
}
The problem is that your return type states Observable<any>, where as you actually return whatever this.genertedData(data) returns (Hint: Sounds like a typo in your function. Guess it should be called generatedData ?).
Best practice would be to move the http call into a service and subscribe to its returned Observable within your component.
So to speak:
// => service.ts
public getCountryObservable(lat,lan):Observable<any> {
return this.http.get(this.googleApi+lat+','+lan+'&sensor=false');
}
Your component would look something like:
// => component.ts
export class YourComponent {
constructor(public yourService: YourService) {}
getCountry(lat, lan): whateverDataTypeYourGeneratedDataReturns {
this.yourService.getCountryObservable(lat, lan).subscribe((data) => {
this.data = this.generatedData(data);
});
}
}
Since the return type of the function is Observable<any>, I guess it should just return this.http.get(this.googleApi+lat+','+lan+'&sensor=false')

How to get the data from BehaviorSubject after its completed?

I have a function that returns a BehaviorSubject but when I try to use the data I get back from the function I need to use it once all the data is back, is there a way to know when the BehaviorSubject is done pulling all the data?
I tried using .finally but it never gets called. Here is the code I'm using.
getData() {
let guideList = '';
this.getChildren(event.node)
.subscribe(
function(data) {
console.log('here');
guideList = data.join(',');
},
function(err) {
console.log('error');
},
function() {
console.log('done');
console.log(guideList);
}
);
}
getChildren(node: TreeNode) {
const nodeIds$ = new BehaviorSubject([]);
//doForAll is a promise
node.doForAll((data) => {
nodeIds$.next(nodeIds$.getValue().concat(data.id));
});
return nodeIds$;
}
Attached is a screen shot of the console.log
Easiest way is to just collect all the data in the array and only call next once the data is all collected. Even better: don't use a subject at all. It is very rare that one ever needs to create a subject. Often people use Subjects when instead they should be using a more streamlined observable factory method or operator:
getChildren(node: TreeNode) {
return Observable.defer(() => {
const result = [];
return node.doForAll(d => result.push(d.id)).then(() => result);
});
}

How do I test Observable.websocket by responding with message in RxJS

I have some RXJS code that does something like the following....
this.webSocketSubject = Observable.webSocket(url);
...
get webSocketStream() {
return this.webSocketSubject;
}
// Other Service
this.socketService.webSocketStream.filter(message => {
return message.method === "logout";
}).subscribe( this.onLogout );
Then in my test I try something like this...
socketService.sendMessage = jasmine.createSpy("Send Message Spy").and.callFake(function() {
socketService.webSocketStream.next(
{
method: "logout",
status: "OK"
}
)
});
// Just to confirm but doesn't get called
socketService.webSocketStream.subscribe(message => console.log("Ok it actually got called"))
But the subscribe code never gets called. I looked for other examples of test WS in RxJS but all I see is this and I can't get something similar working locally.
How do I test Observable.websocket in RxJS?
I had to resort to this but I don't like it.
constructor(private socket: Subject<any> = undefined ) {
if(!socket){
this.webSocketSubject = Observable.webSocket(url);
}
else{
this.webSocketSubject = socket;
}
};

Resources