How can I retrieve information from a Behavior Subject within an Angular service?

My goal in using BehaviouSubject was to streamline API calls and share the data with multiple components within the same route. While I've successfully achieved this, I'm facing challenges when trying to filter the received data.

Here is a stackblitz example that I have put together:

https://stackblitz.com/edit/angular-xtne5y

One of my components displays a table, while the other component needs to extract specific information based on individual object key values (e.g., counting complete/incomplete todos). Due to the necessity of using the async pipe throughout the template, performing operations like filtering becomes impractical. Is there a more efficient way to tackle this issue?

It's crucial for me to maintain reusability of the extracted data.

Answer №1

If you want to achieve the desired outcome, consider incorporating another custom pipe alongside the async pipe to extract specific properties from your data.

I have made modifications to your stackblitz example and implemented the solution. You can view the updated code in action here.

The key is to apply a custom pipe, as demonstrated below:

{{ todos$ | async | myCustomFilter }}

In the provided example (on stackblitz), I have utilized the following:

    <p>
      Number of Completed Todos: {{ (todos$ | async | filterByCondition: {property: 'completed', value: true}).length }}
    </p>

    <p>
      Number of Incomplete Todos: {{ (todos$ | async | filterByCondition: {property: 'completed', value: false}).length }}
    </p>

Update based on feedback

You have two options to achieve your objective: 1) Implement a custom pipe, where you can customize the conditions similar to what has been demonstrated, or create your own logic for evaluation by passing parameters to the pipe (as shown in the example with the args property).

For instance:

    <div>{{$todos | async | filterTodo: 'byDate'}}</div>

You can then handle the logic within your pipe filterTodo based on the 'byDate' value.

2) Utilize different observables for distinct data sets.

  class MyComponent {
    todos$;
    completedTodos$;
    constructor() {
        this.todos$ = this.someService.getTodos(); // from behavior subject
        this.completedTodos$ = this.todos$.pipe(
            filter((item) => {
                // Add your filtering logic here
            })
        )
    }

  }

Answer №2

In my experience working on projects involving creating TODO lists, I have found that subscribing to the URL to fetch data and setting up a Redux Store is an effective approach. You can find more information about this approach in this article.

interface ProductTodos {
    product: {title:string,iscompleted:boolean,id:string/number},
    todos?: any[]
}

By dispatching actions like "PUSH" when fetching Todos, you can append each TODO as an object of type product to the todos array in the interface.

When instantiating the redux Store in the Component Class, loop through the "todos" array to check for id and isCompleted status.

This allows you to iterate through each object and populate your tables according to their completion status.

You can also view my ReduxDemo in Angular 4 by visiting this link.

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

The licensed Angular Google Map component is failing to display the map

I've been experimenting with the new Google Map component developed by the Angular Team (from the package @angular/google-maps) with the help of this insightful tutorial. Unfortunately, I'm facing an issue where the map isn't being displaye ...

Tips for steering clear of global variables while coding in JavaScript

What is the best way to avoid using global variables in JavaScript? //load more var totalItems = $("#myList li").size(); var startIndex = 3; $('#myList li:lt(' + startIndex + ')').show(); $('.loadmore').on('cli ...

Modifying the CSS class of an element does not produce the desired effect after altering its styles using JavaScript

html: <input id="myinput" class="cinput" type="image" src="http://www.foodwater.org.au/images/triple-spiral-3-small-button.jpg"/> <br><br><br><br> <button id="s">set to visible class</button> <button id="h"> ...

JavaScript - Merging the two JSON requests into a unified object

Is there a way to merge two different JSON responses into a single object for easy data manipulation? I've explored various solutions, but none seem to align with my current code structure. Given that I'm new to this, it would be incredibly hel ...

What is the best way to list the choices associated with a specific category?

The Node.js package I'm currently working with requires an argument of a specific type, which I can see is defined through a TypeScript declaration as follows: export declare type ArgType = 'A' | 'B' | 'C'; I am interes ...

Protector of the young travelers' paths

I have encountered a recurring issue with implementing Guards on my pages. Despite referencing multiple solutions from StackOverflow, none of them seem to work for me. Take this example for instance. This is my first attempt at restricting access to cert ...

Tips for sending AngularJS expressions to a controller

I am looking to pass a value from an AngularJS Expression to the controller. Here is the HTML code : <div data-ng-controller="AlbumCtrl"> <div data-ng-repeat="z in songInfo"> <div data-ng-repeat="b in z.album& ...

Exploring ThreeJs with HSL Color Palettes

Struggling with using HSL colors in ThreeJs. Check out my code: var exampleColor = new THREE.Color( 0xffffff ); exampleColor.setHSL( getHSLColour(exampleObject) ); var exampleMaterial = new THREE.MeshLambertMaterial ( {color: exampleColor} ); The result ...

Having trouble accessing ms-appdata:///local directory after capturing a photo

Having an issue with my Cordova application designed for Windows 8.1, I am trying to capture a photo and display it on the screen while also saving it in the local folder. Within one of my directives, I have the following function: scope.takePhoto = func ...

issues with passing values on second click using ajax and jquery

Just starting out with JavaScript, jQuery, and AJAX and running into issues with a basic script to load more data from a database upon button clicks. The first load more button click works fine. But subsequent clicks do not pass values and do not execute. ...

Dynamic content loading for Twitter Bootstrap Popover using Ajax

Below is my code for dynamic content loading in a popover using AJAX. The popover displays correctly after the initial load, but there is an issue with its behavior on the first "show" event – it appears and disappears immediately. $("a.mypopover"). ...

Typescript - Ensuring object assignment with additional property does not result in failure

What is the reason why the code does not fail when executing a = b ? Check out this link type A = { x?: number y?: number } type B = { x?: number z: number } let a: A = {} let b: B = {z: 1} a = b // does not fail a = {z: 1} // fails ...

Creating a layered effect by overlaying one image on top of another in an HTML5

Currently, I am facing an issue with drawing a level field inside my canvas. The images of the tank and enemies are being drawn underneath the field image, which is causing some problems as they should actually be moving above the field. Here is a link t ...

Sharing the input value with a service in Angular 4

I am a beginner when it comes to Angular 4. I currently have a variable named "md_id" which is connected to the view in the following way. HTML: <tr *ngFor="let item of driverData"> <td class="align-ri ...

Standalone JSON Hyperlinks within a Table Column

My webpage features a table filled with information from a JSON API. Currently, I am struggling to create unique links in the far right column of the table. The issue is that all rows are linking to the same HTML page (12345), which is not ideal. What I w ...

Filtering strings in React using the .includes() method results in an empty array

Whenever I run this sample code in a sandbox environment, it functions properly. However, when implemented in my functional component, it fails to work. I have trimmed down the code to include only the essential parts for demonstration purposes. The state ...

Checking if a Vector3 is visible within a camera's field of view using three.js

Is there a simple and cost-effective way to determine if a point or Vector3 is within the field of view of a camera using three.js? I would like to create a grid of boxes to cover the "floor" of a scene, but only up to the edges of the visible area, witho ...

Displaying a sub-menu for specific menu options to fetch content using routes in ReactJS

Currently, I am in the process of learning the React JavaScript library. My goal is to develop a basic web application that consists of a menu, submenu, and content sections. For this project, I am using react 15.0.2, react-router 2.4.0, babel 6.5.2, and w ...

A guide on implementing multiline properties in a property file for Selenium WebDriver

At the moment, I am focusing on utilizing Selenium WebDriver with code that is developed in Java. In the snippet below, I have successfully verified if the dropdown values match the UI for one dropdown. Now, I aim to extend this capability to check multip ...

Learn how to create a smooth and consistent horizontal image slider using JavaScript to manipulate transition transforms

Does anyone know how to create a seamless sliding effect for a series of images in Vuejs? Let's say we have images 1, 2, 3, 4, and 5 When the first slide occurs, the order of images should be: 2, 3, 4, 5, 1 For the second slide: 3, 4, 5, 1, 2 And ...