What is the best way to troubleshoot the type of data being sent to the subscriber of an Angular observable?

I am new to the world of Angular-7, RxJS-6, and Visual Studio Code. Currently, I am facing a challenge with debugging an Observable that is being returned to a subscriber, resulting in a "TypeError" at runtime. It seems like this issue is not uncommon among developers. Can anyone provide guidance on how I can identify what the subscriber is observing or spot any errors in the code below?

In More Detail

I am working on a basic proof of concept using Visual Studio Code and Angular-7 CLI to fetch the current system date/time from a server using Angular's httpclient and display it.

Take a look at the method instrument.service.ts::getSystemTimeDate() below. The HTTP request is successful as we get the following JSON response:

{
  "SystemDateTime": "2018-11-26T08:54:06.894Z"
}

Within the map operator, this response gets converted first to an object of type SystemDateTimeResponse and then to a Date. The goal is to return an Observable<Date> to subscribers. However, I am struggling with how the component subscribes to this Observable<Date>. At runtime, the subscriber in the method onTimeDateBtnClick() throws the error mentioned above:

ERROR
TypeError: You provided an invalid object where a stream was expected...

I suspect that my issue lies in not correctly returning an Observable and possibly messing up the use of the map operator. What am I overlooking here?


The Source Code

The key components in this snippet are:

timedate.component.html: contains a simple template

<p>
  Last time checked: {{today | date:'medium'}}
</p>
<button mat-button (click)="onTimedateBtnClick()">Update</button>

timedate.component.ts: defines the display property today and the event handler onTimedateBtnClick() which uses a data service for managing HTTP requests/responses to retrieve the current date/time from a server.

import { Component, OnInit } from '@angular/core';
import { InstrumentService } from '../instrument.service';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-timedate',
  templateUrl: './timedate.component.html',
  styleUrls: ['./timedate.component.css']
})
export class TimedateComponent implements OnInit {

  /** Display property */
  today: Date;

  /**
   * Constructor
   * @param - data service
   */
  constructor(private dataService: InstrumentService) {
  }

  ngOnInit() {
    this.today = new Date();  /// initialise with client's date/time
  }

  /**
   * User event handler requesting system time/date from the server
   */
  onTimedateBtnClick() {
    const http$: Observable<Date> = this.dataService.getSystemTimeDate();

    http$.subscribe(
      res => this.today = res,
    );
  }
}

instrument.service.ts: includes the getSystemTimeDate() method that returns an Observable<Date>. Though simplified, the code still results in failure to better understand donde exaggerated use of the map operator.

import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs/operators';

// App imports
import { SystemDateTimeResponse, SystemDateTimeUrl } from './instrument.service.httpdtos';


@Injectable({
  providedIn: 'root'
 })
export class InstrumentService {

  constructor(private http: HttpClient) { }

  /**
   * Return the server date and time
   */
  public getSystemTimeDate(): Observable<Date> {
    // Convert the server response object into an observable date
    const responseObject: Observable<Date> =
    this.http.get<SystemDateTimeResponse>(SystemDateTimeUrl.Url).
      pipe(
        map(jsonResponse => {
          const newDto = new SystemDateTimeResponse(jsonResponse.SystemDateTime);
          const d = new Date(newDto.SystemDateTime);
          return d;
        }),
      );

    return responseObject;
  }
}

instrument.service.httpdtos.ts: Contains definitions for data transfer objects.

/** URL - Instrument system date/time */
export class SystemDateTimeUrl {
  public static readonly HttpVerb = 'GET';
  public static readonly Url = 'api/instrument/systemdatetime';
  public static readonly Summary = 'Query the instrument current date/time';
}

/** Response DTO */
export class SystemDateTimeResponse {
  constructor(public SystemDateTime: string) {} 
}

Answer №1

There are two approaches you can take to debug your application. If you are using Chrome, you can utilize the developer tools to add breakpoints in your webpack source code for debugging purposes. Finding the necessary sources may be a bit challenging, but once located, the process should be straightforward. https://i.sstatic.net/WuIlI.png

Alternatively, if you prefer using Intellij IDEA / WebStorm, you have the option to debug the app directly within your editor. To do this, you will need to install the JetBrains IDE Support extension in Chrome / Firefox and configure your editor by adding a new Configuration: Editor Configuration -> Javascript Debugger. Make sure to specify the correct port if your app is running on a different port. https://i.sstatic.net/l7Jid.png Once both the app and debugging configuration are set up, you can add breakpoints in your code (such as in callback functions or map functions) to inspect the variables at those points.

If you have any further inquiries, feel free to ask.

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

Steps to Validate a Form: To allow the submit button to be enabled only when all input fields are filled out; if any field is left empty,

Is it possible to enable the send offer button only after both input boxes are filled? I'm sharing my code base with you for reference. Please review the code and make necessary modifications on stackblitz 1. example-dialog.component.html <form ...

Unraveling the complexities of Typescript's Advanced Type NonFunctionPropertyNames

Delving deeper into the realm of advanced types in Typescript, I came across an intriguing type called NonFunctionPropertyNames. This type is designed to extract only the properties of a given object that are not functions. type NonFunctionPropertyNames&l ...

When utilizing the Angular library in an Ionic project, make sure to call the inject() function within an injection context

I have been working on a project that involves an angular workspace containing an angular web app and an angular ionic app. In an effort to reuse my existing authentication service, which utilizes AngularFireauth and AngularFirestore, I extracted the servi ...

Replace Nebular theme with a new design for a single component

I am currently using Nebular in my Angular application and I am trying to figure out how to customize the theme settings for a specific component on just one page, without affecting other instances of the same component that are using the default settings. ...

Adding an item to an array in Angular 2 using JavaScript!

In my Angular2 form, I have a field that consists of an array of objects. I've successfully created a table with a Delete Row button for each row and an Add Row button using the push() and slice() methods in JavaScript. However, there's a major ...

TS will not display an error when the payload is of type Partial

Why doesn't TypeScript throw an error when making the payload Partial? It seems to only check the first value but not the second one. type UserState = { user: User | null; loading: boolean; error: Error | null } type UserAction = { type: type ...

What is the reason for sending a single file to the server?

A function called "import File" was developed to send multiple files to the server, but only one file is being received. Input: <input type="files" id="files" name="files" multiple onChange={ (e) => this.importFile(e.target.files) } ...

Issue with the proper functionality of the this.formGroup.updateValueAndValidity() method in Angular 6

Currently, I am facing an issue where I need to add or remove validators in a formGroup's controls based on certain conditions. When I try to update the validators using `formGroup.updateValueAndValidity()` for the entire form, it does not seem to wor ...

What is the best approach for injecting services (local and API) in Angular 13 based on different environments (local and QA)?

api-local.service.ts import { Injectable } from '@angular/core'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { LoginRequest } from '../login/login-request'; @Injectable({ providedIn: 'root&ap ...

Enhance the appearance of the table footer by implementing pagination with Bootstrap Angular6 Datatable styling

I utilized the angular 6 datatable to paginate the data in a table format. https://www.npmjs.com/package/angular-6-datatable Everything is functioning properly, but I am struggling with styling the footer of mfBootstrapPaginator. The items appear stack ...

Guide to implementing a universal animated background with Angular components

I'm having trouble figuring out why, but every time I attempt to use a specific code (for example: https://codepen.io/plavookac/pen/QMwObb), when applying it to my index.html file (the main one), it ends up displaying on top of my content and makes ev ...

Setting up TypeScript to function with Webpack's resolve.modules

Imagine having a webpack configuration that looks like this: resolve: { extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'], modules: ['my_modules', 'node_modules'], }, You have a ...

Carousel-item height in Bootstrap 4.6

I am facing an issue with a component in Angular 14 using Bootstrap v4.6: <div id="carouselExampleIndicators" class="carousel slide" data-ride="carousel"> <div class="carousel-inner"> <div cl ...

Encountered a problem while trying to set up the Angular Material Library that has been cloned from

Trying to setup a library that has been forked from https://github.com/angular/material2. git clone <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="63040a1723040a170b16014d000c0e">[email protected]</a>:vugar005/m ...

Having trouble with React Hook Form controlled input and typing

My application utilizes the react-hook-forms library along with the office-ui-fabric-react framework. To integrate the framework inputs, I wrap the 3rd party component using the <Controller> element. The current setup is functional as shown below: ...

Is there possibly a problem with GridActionsCellItem and its props?

I'm encountering a problem with passing props into the GridActionsCellItem within the '@mui/x-data-grid'; columns; { field: 'actions', type: 'actions', width: 80, getActions: (params: any) =&g ...

NextJS applications can encounter issues with Jest's inability to parse SVG images

Upon running yarn test, an unexpected token error is encountered: Jest encountered an unexpected token This typically indicates that Jest is unable to parse the file being imported, suggesting it's not standard JavaScript. By default, Jest will use ...

Transitioning an AngularJS factory to TypeScript

I'm currently in the process of transitioning an AngularJS application to Angular and one of the challenges I've encountered is converting my JavaScript code to TypeScript. While I've been successful with components and services, factories h ...

Exporting stylesheets in React allows developers to separate

I am trying to figure out how to create an external stylesheet using MaterialUI's 'makeStyles' and 'createStyles', similar to what can be done in React Native. I'm not sure where to start with this. export const useStyles = m ...

Looking for a way to style the user's selection in a Ng Bootstrap typeahead component without using resultFormatter?

I have implemented a ngBootstrap typeahead for selecting a person from a list of results. Each result, which is an object retrieved from an API, is displayed as Name + ID in the list by using the resultFormatter input. However, after clicking on a result, ...