What is the best way to include an Observable in this function?

Every time I send a set of credentials to my API and receive the data that needs to be stored, I encounter an error during the login process.

Error: TypeError: You have provided an invalid object when a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

In my code snippet below, I attempted to replace res['user_id'] with this.user['user_id'], but it resulted in an error stating that it cannot read user_id of null.

Here is the code snippet for the service responsible for posting credentials and managing storage:

user = null;
  refreshToken = null;
  private authenticationState = new BehaviorSubject(false);
  public authenticationState$ = this.authenticationState.asObservable();
...
checkToken() {
       this.storage.get(TOKEN_KEY).then(access => {
           if (access) {
               this.user = this.helper.decodeToken(access);
               this.authenticationState.next(true);
           }
           else {
            this.storage.get(REFRESH_TOKEN_KEY).then(reaccess => {
                this.user = this.helper.decodeToken(reaccess);
                this.authenticationState.next(true);
            });
           }
       });
   }

 apilogin(username: string, password: string) {
    return this.http.post<any>(`http://127.0.0.1:8000/api/token/`, { username, password })
    .pipe(
        switchMap((res: any) => {
            // run all in parallel
            return forkJoin(
                this.storage.set(TOKEN_KEY, res['access']),
                this.storage.set(USERNAME_KEY, username),
                this.storage.set(USER_ID, res['user_id']),
                this.user = this.helper.decodeToken(res['access'])
            );
          }),
    // now we know for sure storage values have been set,
    // therefore call checkToken()
        tap(() => this.checkToken()),
        catchError(e => {
            this.showAlert('Oops something went wrong!');
            throw new Error(e);
        }));

}

apilogout() {
      this.storage.remove(USER_ID),
      this.storage.remove(REFRESH_TOKEN_KEY),
      this.storage.remove(USERNAME_KEY),
      this.storage.remove(TOKEN_KEY)
  }

The following code snippet is from my login page.ts file where I always encounter an error which leads to the mentioned log:

apiSubmit() {
  console.log('Hello World');
  this.submitted = true;

  // halt if form is invalid
  if (this.loginForm.invalid) {
      return;
  }
  this.isLoading = true;
  this.loadingEl.present();
  this.authService.apilogin(
  this.f.username,
  this.f.password)
      .pipe(tap(x => this.loadingEl.dismiss()),
      )
      .subscribe(
        data => {
          console.log('0');
          this.router.navigate([this.returnUrl]);
        },
        error => {
          console.log('1');
          this.loadingEl.dismiss();
          this.error = error;
          console.log(error);
          this.isLoading = false;
        }
      );
}

Answer №1

It appears that the parameters passed to forkJoin are being treated as a plain object, causing an error. To resolve this issue, you can easily convert them into observables using rxjs.

 // import the of function
 import { of } from 'rxjs';

 // include the rest of your code here and make sure to import the above

 apilogin(username: string, password: string) {
    return this.http.post<any>(`http://127.0.0.1:8000/api/token/`, { username, password })
    .pipe(
        switchMap((res: any) => {
            this.user = this.helper.decodeToken(res['access'])
            // execute all tasks in parallel
            return forkJoin(
                of(this.storage.set(TOKEN_KEY, res['access'])),
                of(this.storage.set(USERNAME_KEY, username)),
                of(this.storage.set(USER_ID, res['user_id'])),
                of(this.user)
            );
          }),
    // ensuring that storage values have been set before calling checkToken()
        tap(() => this.checkToken()),
        catchError(e => {
            this.showAlert('Oops something went wrong!');
            throw new Error(e);
        }));

}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How to set the default theme color for the mat-sidenav background in Angular 6 and 7?

Is there a way to make the background of a mat-sidenav match the theme color of my mat-toolbar? In the file src\styles.scss, I have the following: @import '~@angular/material/prebuilt-themes/indigo-pink.css'; The template / HTML file incl ...

Issues with Angular 9 routerLinkActive functionality causing unexpected behavior

Whenever I navigate to a different router link, the previous link remains active, resulting in multiple active links with the same class. <div class="side-link" [routerLink]="['/']" [routerLinkActive] = "['link-active']">Dashboar ...

What is the best way to invoke a component method from an event listener of a different component using ($on)?

I recently came across information on Non-Parent-Child Communication at https://v2.vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication, which explains the concept of using bus events to communicate between components. However, I'm still ...

Express.js throwing an unexpected 404 error

I'm really struggling to understand why Node (express) only renders the index page and returns a 404 error for other pages, like "comproAffitto" in this example. In my app.js file: var index = require('./routes/index'); var comproAffitto= ...

The first parameter in Vue router is optional

Is there a way to make the first parameter in my list of routes optional? I want the parameter to change a header in my api calls if it's present in the url, but everything else should stay the same. Instead of creating two sets of routes to handle t ...

Hidden Document Scroll Offset

When CSS is used to hide scrollbar html, body { width: 100%; overflow-x: hidden } The above code snippet removes the scroll from the window but triggers it on the body element. To calculate the scroll values in such cases, you can use: pageOffset = ...

Streamline event listeners with a pair of attributes

I am working with a function that requires one parameter: function magical(element){ ... } In my project, I have multiple click handlers attached to different elements and classes that are invoking this function: $('#div1').click(function(){ ...

Fill the next Thursday with JavaScript

I'm having trouble updating the date for the upcoming Thursday using JavaScript. The current script works fine until the end of the month, but if it's the 25th of August, the output will be "Next Thursday - 8/32/2022". I need a more intelligent s ...

I am constantly encountering the error message "Reading 'Linear'' error due to undefined properties in my threejs code

A procedural generation library for threejs caught my attention Here is the link to the library: https://github.com/IceCreamYou/THREE.Terrain Despite following the instructions provided in the ReadMe.md file, I encountered an error that says: Cannot read ...

Jquery Issue: Safari Leaves Alert Messages Unclosed When Opening Next Alert

I am experiencing an issue in Safari Browser and need some help with the following scenarios (with Example). When I click a button to delete an account, an alert message pops up. This alert window has two actions - "OK" and "Cancel". If I click "OK", it r ...

How can Codeception/Selenium help in testing the tooltip or customValidity message?

I am trying to implement a feature in my Codeception scenario where I want to validate a form submission with user errors, such as confirming a wrong email address, and display a custom tooltip message in the browser. HTML <form ... > <label ...

Display the Astro component based on the query of the current page's type

I am using Astro, GraphQL (Apollo Client), Typescript and React. Within my dynamic route: [...slug].astro file, I have a requirement to conditionally display a specific Astro component. I was able to achieve this using the following logic: {data.page.ty ...

Storing form data efficiently with a single key and multiple values using a POST API request

I've encountered a challenge while trying to save form data in a format where there's the same key but different values separated by commas. While I can successfully submit form data via POST for single "key/value" pairs, I'm struggling with ...

Sending a JavaScript array to a Ruby on Rails controller by utilizing a hidden form field

Having explored numerous solutions that did not fit or resolve my issue, I am turning to this platform with my question: I utilize JavaScript to populate hidden fields in a form with data and transmit it to a Ruby on Rails controller. While this process w ...

Using Javascript outside of the AngularJS environment

I am trying to utilize Javascript functions outside the controller in Angular JS instead of using a service within a module. Is this allowed? For instance: var UrlPath="http://www.w3schools.com//angular//customers.php" //this section will store all the f ...

Filter information by the K column within Google Script Editor on Google Sheets

For this particular case, I have data coming from a Google Sheet (4Cat) that is being transferred to another sheet (ImportFeeder) where my Google Script is executed. After executing the script provided below, I am looking to implement a filter script at t ...

Python raises a KeyError if JQuery is included

I have encountered an issue with the code snippet below, where I am attempting to define a variable within the HTML. Oddly enough, when I exclude the JQuery script, everything functions as expected. However, upon reintroducing the JQuery script, the functi ...

Enable the ability to upload multiple images on a single page using droparea.js

I am currently utilizing droparea js for uploading images. However, I have encountered an issue where if I try to upload an image in one of the upload menus, it ends up changing all four upload menus simultaneously. <div class="col-md-12"> ...

I am facing an issue where the data is not being populated in my form even though I am using ng

Here is a form with grouped inputs using the ngModelGroup directive: <form #form="ngForm" (ngSubmit)="submit(form.value)"> <fieldset ngModelGroup="user"> <div> <label>Firstname:</label> < ...

Edge fails to access Webservice from file:/// host

When attempting to access a webservice that I've created in C# using Typescript and the fetch-api, everything works smoothly in Chrome and Firefox. However, in Edge, the access fails. I've tried both POST and GET methods in Edge, but neither are ...