Error in BehaviorSubject<any[]>: Unable to assign type 'any[] | null' to type 'any[]'

When I try to pass a BehaviorSubject from my CacheService to a component @Input() that expects an array, I encounter an error stating that 'any[] | Type 'any[] | null' is not assignable to type 'any[]'. This occurs even though the BehaviorSubject is initialized with an empty array as the default value in the service. I'm puzzled by this issue and have provided a condensed version of my app below to demonstrate the problem. Any assistance would be greatly appreciated.

app.component.html

<app-custom-select [options]="this.items$ | async"></app-custom-select>

app.component.ts

import { Component } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { BehaviorSubject, ReplaySubject, Subject } from 'rxjs';
import { CacheService } from './services/cache.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: './app.component.scss'
})
export class AppComponent 
{
    items$ = this.cache.items.data$;
    constructor(private cache: CacheService) {}
}

cache.service.ts

import { Injectable } from '@angular/core';
import { CacheArray } from '../models/CacheArray';

@Injectable({
  providedIn: 'root'
})
export class CacheService 
{
    items = new CacheArray<any>();
}

cache.ts

import { BehaviorSubject, Observable } from "rxjs";

export class CacheArray<T>
{
    data$ = new BehaviorSubject<T[]>([]);

    load(obs: Observable<T[]>)
    {
        obs.subscribe((items: T[]) => {
            this.data$.next(items);
        });
    }
}

custom-select.component.ts

import { Component, Input, OnInit } from '@angular/core';

@Component({
  selector: 'app-custom-select',
  templateUrl: './custom-select.component.html',
  styleUrls: ['./custom-select.component.scss']
})
export class CustomSelectComponent
{
    @Input()
    options: any[] = [];
}

I did not anticipate encountering this error.

Answer №1

When working with a BehaviorSubject, it is important to remember that it always assigns the latest value to all of its subscribers. Therefore, when initializing a BehaviorSubject, make sure to provide an initial value.

One common error that can occur is if the initial value is set as an array type, such as any[], and then later an attempt is made to update it with a null value.

To avoid this error, it is recommended to add a check before updating the value in the BehaviorSubject. This way, you can ensure that the error is resolved.

if(items != null) {
    this.data$.next(items);
}

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

Passing data from a container component to a Redux Form component in React with TypeScript

One of my Form container components looks like this: class PersonalDetailContainer extends React.Component<PropTypes> { onSubmit = async (fields: PersonalFields) => { this.props.savePersonalDetail(fields); }; render(): JSX.Element { ...

What causes the issue of Angular 9 routing breaking upon page refresh?

I have deployed my Angular 9 application on Heroku and everything is working perfectly. However, when I refresh the page or copy/paste a link, I get an error message saying "Cannot GET /XXX/XXX". Only the root link seems to work! Initially, I can navigate ...

Discover the power of TypeScript's dynamic type inference in functions

Below is a function that selects a random item from an array: const randomFromArray = (array: unknown[]) => { return array[randomNumberFromRange(0, array.length - 1)]; }; My query pertains to dynamically typing this input instead of resorting to u ...

Utilizing Vue and Typescript for efficient dependency injection

After attempting to use vue-injector, I encountered an issue as it was not compatible with my version of Vue (2.6.10) and Typescript (3.4.5). Exploring other alternatives, there seem to be limited options available. Within the realm of pure typescript, t ...

Position the float input to the right on the same line as an element

This Angular code contains a challenge where I aim to have text at the start of a column and an input box on the right side of the page, both aligned on the same line. The issue lies in the code which floats the input to the right but disrupts the alignme ...

Transforming the Server-side model to the Client-side model within Angular 4

My Server-side C# model public class Instructor:Entity { public string Name { get; set; } public string PhoneNo { get; set; } } Client-side TypeScript model export class Instructor extends Entity { public name:string; public address ...

How can you implement a null filter in the mergeMap function below?

I created a subscription service to fetch a value, which was then used to call another API. However, the initial subscription API has now changed and the value can potentially be null. How should I handle this situation? My code is generating a compile e ...

"Can you provide tips on how to automatically close a dropdown select menu when the mouse

<div class="row"> <div class="col-sm-6 no-right-border"> <div class="form-group"> <label for="inputFirstName">Filter:</label> <select class="form-control c ...

Necessitating derived classes to implement methods without making them publicly accessible

I am currently working with the following interface: import * as Bluebird from "bluebird"; import { Article } from '../../Domain/Article/Article'; export interface ITextParsingService { parsedArticle : Article; getText(uri : string) : B ...

The modal feature on ng-bootstrap.github.io is failing to function properly when used with the Bootstrap3 CSS

Struggling to understand why the modal displays when using Bootstrap 4 with ng-bootstrap, but not displaying with Bootstrap 3. ...

Tips on informing the TS compiler that the value returned by a custom function is not null

There might be a way to make this code work in TypeScript, even though it's currently showing some errors regarding possible undefined values. Take a look at the code snippet: const someArray: foo[] | null | undefined = [...] // TS fail: someArray ...

Angular Form Styles by Formly

I am experimenting with Formly for Angular and PrimeNG for the first time. However, the provided example does not look good: https://stackblitz.com/edit/ngx-formly-ui-primeng?file=src%2Fapp%2Fapp.component.ts Here is the original example they provide: ...

Navigating to a new link containing query parameters

I am working on setting up a redirect in Angular 6 The process for the redirect is quite simple as outlined below: Obtain destination URL from parameters: this.returnUrl = this.route.snapshot.queryParams['route'] || '/'; Perform Red ...

The properties '{ label: string; value: string; }' are required in type 'readonly never[]' for react-select, but they are missing

state = { groupPermissionValue: {label: '', value: ''}, } <Select instanceId="user-group" onChange={this.selectUserGroupOption} value={this.state.groupPermissionValue} options={this.state.groupPermission} i ...

Improper Alignment of Bootstrap 4 Navbar Link: Troubleshooting Required

Take a look at the image for the issue: https://i.stack.imgur.com/u9aCy.png As shown in the image, the NavBar links are stacked instead of being displayed in one row. This is the HTML code I have used: <!doctype html> <html> <head> ...

What is the internal mechanism used by Angular for routing implementation?

My traditional belief about web browsers has been challenged by the behavior of Angular. I used to think that when a user enters a new URL, the browser would fetch a whole new page from the network and display it, replacing the old one. But with Angular, ...

Tips for creating a script that waits for a specific amount of time before moving on to the next execution block in Protractor

Need to automate a test case that involves filling out a form with 5 date pickers and 30 fields. Once the form is filled, a jar needs to be invoked to retrieve the data from the DB and process it independently. Note: The jar does not send any value back t ...

Consider the presence of various peer dependency versions in a react-typescript library

Currently, I am in the process of converting my react component library react-esri-leaflet to typescript. This library requires the user to install react-leaflet as a peerDependency and offers support for both react-leaflet version 3 (RLV3) and react-leafl ...

Error: zsh is unable to locate the command, even after defining it in package.json bin and installing it globally

I attempted to create a command-line application using TypeScript. Below is the code I have written: //package.json { "name": "jihea-cli", "version": "1.0.0", "description": "", "main": "index.ts", "bin": { "cli": "./bin/index.ts" }, // ...

Stop /Terminate the Angular 2 HTTP API request

Occasionally, the loading time for an http API call can be quite lengthy. However, even if we navigate to another component, the call still continues execution (which is visible in the browser console). Is there a method or approach that allows us to can ...