.toPromise().then(...).catch(...).finally is not a function - rxjs

I'm getting this error on Firefox and I'm using rxjs 6.5.4 version:
Unhandled promise rejection TypeError:
this.service.getPastData2(...).toPromise().then(...).catch(...).finally
is not a function
My code:
lineMap(criteria: ReportCriterionModel){
this.service
.getPastData2(
criteria.deviceIds[0].toString(),
criteria.vehiclePlates[0].toString(),
criteria.startDate,
criteria.finishDate)
.toPromise()
.then(
(data) => {
this.loadDataToMap(data);
this.filterData = criteria;
},
(err) => {
if (err.status == 400) {
this.isLoadingFms.next(false);
}
}
)
.catch(
(err) => {
console.log(err);
}
)
.finally(
() => {
this.isLoadingFms.next(false);
}
)
}

Related

AngularFireAuth signInWithEmailAndPassword callback is never thrown when deploying for iOS using Ionic Capacitor

I built a webapp using Ionic 3, Angular 12, Firebase 9, AngularFire.
When I try to authenticate (on iOS) the callback is never thrown from this function and therefore the authentication is never performed although the requests are executed with a status code of 200. On the web the authentication works as intended.
import { AngularFireAuth } from "#angular/fire/compat/auth";
...
async loginWithEmail(email: string, password: string) : Promise<void> {
return new Promise<User>((resolve, reject) =>
this.afAuth.signInWithEmailAndPassword(email, password).then(
(res) => {
resolve(res.user);
},
(error: { message: string }) => {
reject(error);
this.toastService.present({
message: "Something has gone wrong. Please try again.",
duration: 3000,
color: "warning"
});
console.error(error.message);
}
)
).then(
(result: User) => {
if (result) {
this._user.next(result);
} else {
if (result != null) {
this.zone.run(() => {
void this.router.navigate(['tabs', 'home']);
});
}
}
},
(error: { message: string }) => {
this.toastService.present({
message: error.message,
duration: 3000,
color: "warning"
});
}
);
}
What can I do about this behaviour?

Promise resolve output message will empty. How to solve the problem

In backend program, i use new Promise(resolve, reject). When it success post data to database, it will output empty. How make it output "success! article_id: 1"?
const createArticle = (insertValues) =>
{
return new Promise((resolve, reject) =>
{
connectionPool.getConnection((connectionError, connection) =>
{
if(connectionError)
{
reject(connectionError);
}
else
{
connection.query('Insert into Article set?', insertValues, (error, result) =>
{
if(error)
{
console.error('sql error: ', error);
reject(error);
}
else if (result.affectedRows === 1)
{
console.log(result.insertId);
resolve(`success! article_id: ${result.insertId}`);
}
connection.release();
});
}
});
});
};
i use the program to call createArticle.
const articlePost = (req, res) =>
{
const insertValues = req.body;
articleModule.createArticle(insertValues).then((result) =>{
res.sent(result);
}).catch((err) => { return res.send(err); });
};

Moxios Requests State Not Cleared In Between Tests

My specs are behaving weirdly in that when I run the tests alone, they pass. However, when I run the test suite all together, the failure tests still continue to use the success axios mock instead of using the correct failing http axios mock. This results in my tests failing. Am I missing something for isolating the 2 mocks from each other in the different portions of code?
jobactions.js
export const loadUnassignedJobs = (job_type) => {
if (!['unscheduled', 'overdue'].includes(job_type)) {
throw 'Job Type must be "unscheduled" or "overdue".';
}
return (dispatch) => {
dispatch({type: JobActionTypes.LOAD_UNASSIGNED_JOBS_STARTED, job_type });
return axios.get(defaults.baseapi_uri + 'jobs/' + job_type)
.then(function (response) {
dispatch(updateUnassignedJobs(response.data.jobs));
// handle success
})
.catch(function (error) {
// handle error
dispatch({ type: JobActionTypes.LOAD_UNASSIGNED_JOBS_FAILURE, error });
})
.then(function () {
// always executed
});
}
};
export const updateUnassignedJobs = (unassigned_jobs) => {
let unassigned_job_ids = [];
let jobs = {};
for (let job of unassigned_jobs) {
unassigned_job_ids.push(job.id);
jobs[job.id]=job;
}
return({
type: JobActionTypes.LOAD_UNASSIGNED_JOBS_SUCCESS,
jobs,
unassigned_job_ids,
});
};
spec.js
import configureMockStore from "redux-mock-store";
import thunk from "redux-thunk";
import * as jobActions from "../../../app/javascript/actions/JobActions"
import { findAction } from '../support/redux_store'
import * as JobActionTypes from '../../../app/javascript/constants/JobActionTypes'
import fixtures_jobs_unscheduled_success from '../fixtures/jobs_unscheduled_success'
import moxios from "moxios";
export const mockStore = configureMockStore([thunk]);
let store;
describe ('loadUnassignedJobs', () => {
context('when bad parameters are passed', async () => {
it('will raise an error', () => {
const store = mockStore();
expect(() => {
store.dispatch(jobActions.loadUnassignedJobs('wrong_type'));
}).to.throw('Job Type must be "unscheduled" or "overdue".');
});
});
context('when unscheduled is passed', () => {
beforeEach(() => {
moxios.install();
console.log("before each called");
console.log(moxios.requests);
store = mockStore();
store.clearActions();
});
afterEach(() => {
console.log("after each called");
console.log(moxios.requests);
moxios.uninstall();
});
context('on success', () => {
beforeEach(() => {
moxios.wait(() => {
let request = moxios.requests.mostRecent();
request.respondWith({
status: 200,
response: fixtures_jobs_unscheduled_success
});
});
})
it('dispatches LOAD_UNASSIGNED_JOBS_STARTED', () => {
store.dispatch(jobActions.loadUnassignedJobs('unscheduled')).then(() => {
expect(findAction(store, JobActionTypes.LOAD_UNASSIGNED_JOBS_STARTED)).to.be.eql({
type: JobActionTypes.LOAD_UNASSIGNED_JOBS_STARTED,
job_type: 'unscheduled'
});
});
});
it('dispatches updateUnassignedJobs()', () => {
store.dispatch(jobActions.loadUnassignedJobs('unscheduled')).then(() => {
expect(findAction(store,JobActionTypes.LOAD_UNASSIGNED_JOBS_SUCCESS)).to.be.eql(jobActions.updateUnassignedJobs(fixtures_jobs_unscheduled_success.jobs))
});
});
});
context('on error', () => {
beforeEach(() => {
//console.log("before each on error called");
//console.log(moxios.requests);
moxios.wait(() => {
console.log('after waiting for moxios..')
console.log(moxios.requests);
let request = moxios.requests.mostRecent();
request.respondWith({
status: 500,
response: { error: 'internal server error' }
});
});
})
it('dispatches LOAD_UNASSIGNED_JOBS_FAILURE', (done) => {
console.log(moxios.requests);
store.dispatch(jobActions.loadUnassignedJobs('unscheduled')).then(() => {
console.log(moxios.requests);
console.log(store.getActions());
expect(findAction(store, JobActionTypes.LOAD_UNASSIGNED_JOBS_FAILURE)).to.include({
type: JobActionTypes.LOAD_UNASSIGNED_JOBS_FAILURE
});
expect(findAction(store, JobActionTypes.LOAD_UNASSIGNED_JOBS_FAILURE).error).to.include({
message: 'Request failed with status code 500'
});
done();
});
});
it('does not dispatch LOAD_UNASSIGNED_JOBS_SUCCESS', (done) => {
store.dispatch(jobActions.loadUnassignedJobs('unscheduled')).then(() => {
expect(findAction(store, JobActionTypes.LOAD_UNASSIGNED_JOBS_SUCCESS)).to.be.undefined;
done();
});
});
})
});
});
describe('updateUnassignedJobs', () => {
it('assigns jobs to hash and creates an unassigned_job_ids array', () => {
expect(jobActions.updateUnassignedJobs([ { id: 1, step_status: 'all_complete' }, { id: 2, step_status: 'not_started' } ])).to.be.eql(
{
type: JobActionTypes.LOAD_UNASSIGNED_JOBS_SUCCESS,
jobs: { 1: { id: 1, step_status: 'all_complete' }, 2: { id: 2, step_status: 'not_started' } },
unassigned_job_ids: [ 1,2 ]
}
)
});
});
Found the issue!
The it() blocks for the success case were not using the done callback causing the afterEach() moxios.uninstall() to be called prematurely and not resetting the requests after the call was complete. Fixing this, and now all the tests pass.

RxJs How to complete inner observable

I have function like this:
this.eventTaskWorking$ = completeStage
.pipe(
map(result => {
switch (result) {
case Statuses.LAST_TASK: {
console.info('returning finish event observable');
throw { err: 0 };
}
default: {
return EMPTY;
}
}
}),
catchError(() => completeEvent)
)
.subscribe();
When i throw an exception, "completeEvent" is completed, but if i try to use switchMap, mergeMap etc...it's not working:
this.eventTaskWorking$ = completeStage
.pipe(
map(result => {
switch (result) {
case Statuses.LAST_TASK: {
return completeEvent;
}
default: {
return EMPTY;
}
}
}),
switchMap(t => t),
)
.subscribe();
What's wrong?
UPD:
const completeEvent = this.FinishEvent(eventRef, uid);
private FinishEvent(eventRef: Observable<IEvent>, taskUid: string): Observable<any> {
return eventRef.pipe(
switchMap(t => this.UpdateTaskStatus(taskUid, 3)));
}
ok, seems FinishEvent didn't return observable, my fault

Can't call methods inside catch or then of a Promise call

I have a method which returns a promise like:
checkLogin(credentials) {
return new Promise((resolve, reject) => {
this.http.post(url, credentials)
.map(res => res.json())
.subscribe(
data => {
resolve(data);
},
err => {
reject(err);
}
);
});
}
I call this method inside another:
login(credentials) {
this.checkLogin(credentials)
.then(function(result) {
console.log("ok: ",result);
this.doAlert("ok");
})
.catch(function(err) {
console.log("error: ",err.message);
this.doAlert(err.message)
});
}
Here is where the error happens, it is said "TypeError: this.doAlert is not a function":
But the doAlert is in the same file than the others, and it works fine from other places (not promises calls)
doAlert(text) {
let alert = Alert.create({
title: 'Alert;,
subTitle: text,
buttons: ['Ok']
});
this.nav.present(alert);
}
Is it not possible to do this?
Use fat-arrow functions instead
login(credentials) {
this.checkLogin(credentials)
.then((result) => {
console.log("ok: ",result);
this.doAlert("ok");
})
.catch((err) => {
console.log("error: ",err.message);
this.doAlert(err.message)
});
}
to keep the scope
See also
- https://basarat.gitbooks.io/typescript/content/docs/arrow-functions.html
- https://github.com/Microsoft/TypeScript/wiki/'this'-in-TypeScript
- What's the meaning of "=>" in TypeScript? (Fat Arrow)
Use arrow functions
login(credentials) {
this.checkLogin(credentials)
.then((result) => {
console.log("ok: ",result);
this.doAlert("ok");
})
.catch((err) => {
console.log("error: ",err.message);
this.doAlert(err.message)
});

Resources