Unable to transfer data to other components via service

Two components were developed, one to display a list of all loans and the other to view detailed information about each loan upon clicking on a card in the list. Despite being able to see the data console logged within the subscribe function, no data is appearing on the HTML page.

loan.ts

export class Loan
{
    id: number;
    title: string;
    description: string;
    amount: number;
}

list-loan-component.ts

import { Component, OnInit } from '@angular/core';
import * as EventEmitter from 'events';
import { Loan } from '../loan';
import { LoanService } from '../loan.service';

@Component({
  selector: 'app-list-loans',
  templateUrl: './list-loans.component.html',
  styleUrls: ['./list-loans.component.css']
})
export class ListLoansComponent implements OnInit {
  
  loans:Loan[];

  constructor(private loanService: LoanService) { }

  ngOnInit(): void {
    this.loans = this.loanService.getLoans();
  }

  openLoan(loan: Loan)
  {
    this.loanService.loan.emit(loan);   
  }
}

list-loan-component.html

<div class="container">
    <div class="card-deck">
       <div *ngFor="let loan of loans">
           <div class="card" routerLink="/loan/view" routerLinkActive="active"
           (click)="openLoan(loan)">
               <div class="card-header"> {{loan.title}} - {{loan.amount}}</div>
               <div class="card-body">
                   <p class="card-text">{{loan.description}}</p>
               </div>
           </div>
       </div>
    </div>
</div>

view-loan.component.ts

import { ChangeDetectorRef, Component, Input, OnChanges, OnInit } from '@angular/core';
import { ActivatedRoute, ActivatedRouteSnapshot, Params } from '@angular/router';
import { Loan } from '../loan';
import { LoanService } from '../loan.service';

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

  selectedLoan: Loan ;

  constructor(private loanService: LoanService, private router:ActivatedRoute) { }

  ngOnInit() {
    this.loanService.loan.subscribe(loan =>
      {
        this.selectedLoan = loan;     
      }
    );
  }
}

view-loan.component.html

<div class="card text-center">
  <div class="card-header">
    {{selectedLoan['title']}}
  </div>
  <div class="card-body">
    <h5 class="card-title">Loan From :  {{selectedLoan['title']}}</h5>
    <h3 style="text-align: left; text-decoration: underline;">Details:</h3>
    <p class="card-text">{{selectedLoan['description']}}</p>
    <p class="card-text">{{selectedLoan['amount']}}</p>
    <a href="#" class="btn btn-primary">Go somewhere</a>
  </div>
  <div class="card-footer text-muted">
    2 days ago
  </div>
</div>

loan.service.ts

import { Injectable, Output, EventEmitter } from "@angular/core";
import { Loan } from "./loan";
    
@Injectable({
    providedIn: 'root'
  })
export class LoanService
{
    loan = new EventEmitter<Loan>();

    private loans:Loan[] = [
        {
            "id":1,
            "title" : "HDFC Credit Loan",
            "description" :"Loan to clear all credit card payments",
            "amount" : 24958.23
        },
        {
            "id":2,
            "title" : "Aditya birla personal Loan",
            "description" :"Loan to personal expenses",
            "amount" : 12000.00
        }
    ]

    constructor(){}

    getLoans(): Loan[]{
        return this.loans.slice()
    }

    getLoan(id:number): Loan{
        this.loans.forEach(loan =>
            {
                if(loan["id"] === id) 
                    return loan;
            }
        );
        return new Loan();
    }
}

Note: Usage of routing has been implemented as well. If there are any concerns regarding routing causing these issues, please address them accordingly.

Answer №1

Before your ViewLoanComponent loads, it seems that an EventEmitter value is being passed. To fix this issue, simply replace the EventEmitter with ReplaySubject in your code:

export class LoanService
{
    $loan = new ReplaySubject<Loan>(1);
...

Then, update your code like this:

openLoan(loan: Loan)
  {
    this.loanService.$loan.next(loan);   
  }

Additionally, make sure to remove the async pipe from your code snippet:

<div *ngFor="let loan of loans">

Answer №2

To work with observables, it is recommended to avoid using the async pipe on arrays like loans[]. Instead, consider utilizing a BehaviorSubject or an Observable for more efficient data handling. For further information, check out this link

Answer №3

When looking at the list-loans-component.html file, you will notice that there is an iteration over loans using the following code:

<div *ngFor="let loan of loans | async">
. However, it seems that the loans variable is not actually an asynchronous value, as the loan service directly returns an array of loans, rather than an Observable of loan arrays. Simply removing the async pipe should resolve this issue.

By the way, great job on asking such a clear question!

Update:

If you'd like to see your code in action, check out this working example on StackBlitz.

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

Issue encountered with Angular 12 Material table: The data source provided does not match an array, Observable, or DataSource

When my REST API returns the following data: { "id": 1, "userId": 1, "date": "2020-03-02T00:00:02.000Z", "products": [ { "productId": 1, "quantity": 4 }, { "productId": 2, "quantity": 1 }, { "productId": 3, "quantity": 6 } ], "__v": 0 }, I attempt to imple ...

Angular and Firebase: Incorporating user feedback into the frontend data structure

I am new to using Angular and Firebase. My current approach involves logging in with Angular to my Firebase backend and then viewing the response in the console to see all the keys associated with a firebase user. However, I am looking for a way to link th ...

The npm installation process has come to a sudden halt

Starting a web application in Angular 17 has been my goal. I typically run npm install followed by ng serve. However, this process suddenly stopped working. To troubleshoot, here are the steps I've taken: Updated npm to the latest version (10.2. ...

Issue encountered when trying to transfer an image file from Angular to Node.js

My HTML file contains the following form: <form method="post" [formGroup]="orderForm" enctype="multipart/form-data" (ngSubmit)="OnSubmit(orderForm.value)" > <div class="form-group"> <label for="image">Select Branch Image< ...

What happens when a typed Array in Typescript has an undefined property?

I've encountered an issue with a seemingly simple problem that's causing me quite the headache. The code snippet in question is provided below: interface IFoo{ ReturnFirstBarObject1(): string; FillBarArray(array: Array<Bar>): void; } ...

How to showcase the array object nested within an array of objects in Angular 2

Here is the content of my JSON file: country_id:String, name:String scholardetails:[{ country_id:String, scholarshipname:String, scholarshiplink:String }] ...

Display a button only when hovering over it

Seeking assistance for a simple task that is eluding me at the moment. I am currently using scss and trying to make a button only appear when hovered over. The button is hidden in the code snippet below, nested within a block alongside some svgs. Any hel ...

Ways to eliminate the default Bootstrap body style within a component's HTML file

I am facing an issue with my angular widget directive where my custom CSS is getting overridden by Bootstrap default styles when I add the widget to another application component. View my Bootstrap CSS here. I am struggling to remove the font-family in m ...

Developing Angular dynamic components recursively can enhance the flexibility and inter

My goal is to construct a flexible component based on a Config. This component will parse the config recursively and generate the necessary components. However, an issue arises where the ngAfterViewInit() method is only being called twice. @Component({ ...

Having trouble with removing a language from the router in Next.js when using ni18n?

I've been working on a website using ni18n with Next.js, but I'm having trouble removing the language part from the URL even after trying to force remove it. What I'm aiming for is a URL like this: "http://localhost:3000" Howeve ...

Discovering objects nested within other objects

I am currently attempting to locate a specific element within another element. The structure of my HTML looks like this: <div> <label>test</label> <div> <a>testlink</a> <input type=&apos ...

The CORS policy has blocked the Vimeo URL from its origin, stating that the PATCH method is not permitted according to the Access-Control-Allow-Methods preflight response

Using Angular for web development. When uploading a video to Vimeo, it involves 3 steps: Create the video. Upload the video file. Verify the upload. The process of creating a video is successful, however, encountering an error during the vid ...

There is an implicit 'any' type error binding element 'currency' in Graphql React Typescript

I am facing an issue with my code. I want to use the EXCHANGE_RATES in renderedExchangeRates, but I am receiving an error message saying "Error Message: Binding element 'currency' implicitly has an 'any' type." I understand that this is ...

angular: updating fields in an object

I have a database object with the following boolean fields: isRed, isToday, isImportant - along with an Id. Within my UI, I have 3 checkboxes with corresponding inputs in my TypeScript file. How can I go about updating this object? I've attempted to ...

Typescript or Angular 2 for Google Maps

Is there a way to integrate Google Maps Javascript API with Typescript or Angular 2? Although libraries like https://github.com/SebastianM/angular2-google-maps are available, they may not provide full support for features like Events and Places Libraries ...

Experiencing a strange response while attempting to parse the result of an Angular 2 HTTP JSON request

After successfully implementing the http.get call and retrieving data from the request, I encountered an issue: this.http.get('https://data.cityofnewyork.us/resource/xx67-kt59.json').subscribe(data => { // Read the result field from the ...

Switch the MatSlideToggle within an Angular 8 component

I seem to be encountering a persistent error: "ERROR TypeError: Cannot set property 'checked' of undefined" Take a look at my code snippet from test.component.ts: import { Component, OnInit, ViewChild } from '@angular/core'; import { ...

The function item$.take cannot be found, resulting in a TypeError: "item$.take is not a function"

I am currently facing an issue with the take(1) function not working as expected with my Angular Firebase object. I have tried using valuechanges and snapshotchanges as alternatives, but they do not solve the problem for me due to other issues I encounter. ...

Implementing tailwindcss styles in a typescript interface with reactjs

In my code, I have a file named types.ts that defines an interface called CustomCardProps. I pass this interface to the CustomCard component within the home.tsx file. Additionally, I have a folder named constant with an index.ts file where I store values o ...

Utilize NodeJS and Typescript to input data into a postgreSQL database

Here is my code snippet: signup.post('/signup', urlendcodedParser, async(req: Request, res: Response) => { const username = req.body.username; const password = req.body.password; const age = req.body.age; const email = req ...