Exploring the wonders of HTTP requests through pure pipes in Angular 5

I've been working on a pipe that converts currency values from one to another by making an HTTP call. The idea is to pass in the source and destination currencies as parameters.

@Pipe({
    name: "currencyConverter"
})
export class CurrencyConverterPipe implements PipeTransform {

    transform(value: number, currencyPair: string): number {
        let sourceCurrency = currencyPair.split(":")[0];
        let destinationCurrency = currencyPair.split(":")[1];
        this.currencyConverterService.convert(sourceCurrency, destinationCurrency).subscribe(successData => {
            return successData['fiatValue'] * value;
        }, errorData => {
            console.error(errorData);
        })
    }
}

When using it in HTML:

<p> {{ value | currencyConverter:'BTC:USD'}}</p>

However, I'm facing a problem where no value is being displayed on the UI. If I set my pipe to impure, it starts working but results in multiple HTTP calls to the server. Is there a way to make the HTTP call without having to use pure: false in the pipe?

Answer №1

This pipe is not inherently pure.

To prevent multiple requests, it should return the same observable without making additional requests until the input changes. Here's an example:

@Pipe({
  name: "currencyConverter",
  pure: false
})
export class CurrencyConverterPipe {
  private sourceCurrency;
  private destinationCurrency;
  private valueSubject = new Subject();
  private value$ = this.valueSubject.asObservable().distinctUntilChanged()
    .switchMap(value => {
      return this.currencyConverter
        .convert(sourceCurrency, destinationCurrency))
        .map((data) => data * value);
    });

  constructor(private currencyConverter: ...) {}

  transform(value: number, currencyPair: string): number {
    this.sourceCurrency = currencyPair.split(":")[0];
    this.destinationCurrency = currencyPair.split(":")[1];
    this.valueSubject.next(value);
    return this.value$;
  }
}

Since it is meant to be used in conjunction with the async pipe, it would make sense to combine them and extend the functionality of AsyncPipe:

@Pipe({
  name: "currencyConverterAsync",
  pure: false
})
export class CurrencyConverterPipe extends AsyncPipe {
  private sourceCurrency;
  private destinationCurrency;
  private valueSubject = new Subject();
  private value$ = this.valueSubject.asObservable().distinctUntilChanged()
    .switchMap(value => {
      return this.currencyConverter
        .convert(sourceCurrency, destinationCurrency))
        .map((data) => data * value);
    });

  constructor(cdRef: ChangeDetectorRef, private currencyConverter: ...) {
    super(cdRef);
  }

  transform(value: number, currencyPair: string): number {
    this.sourceCurrency = currencyPair.split(":")[0];
    this.destinationCurrency = currencyPair.split(":")[1];
    this.valueSubject.next(value);

    return super.transform(this.value$);
  }
}

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

Choosing the selected option in AngularJS

I am facing a frustrating issue with understanding how AngularJS manages select option values and selections. I have a basic item that I pass to a modal window, which includes a template_id. Additionally, I have a list of templates with names and ids, and ...

Resize the textarea to fit a maximum of five lines, and display a scrollbar if necessary

Explanation: I am facing an issue in Angular 2 regarding the chat screen. I need the chat screen to dynamically increase in size as I type, up to a maximum of 5 lines, and then show a scrollbar. How can I achieve this functionality? Problem: The current b ...

Guidelines on Transferring Variables to a JavascriptExecutor Script

Currently, I am utilizing C# and Selenium to browse through a website and have come across an issue regarding passing variables into my JavaScriptExecutor command. When I attempt to do so using the code below: ((IJavaScriptExecutor)webdriver).ExecuteScript ...

How can I iterate through multiple rows in JavaScript?

Feeling stuck, the simple yet dreaded for loop has become my nemesis and I could really use some guidance. Currently, I have a Google sheet with 3 rows (excluding headers) and 8 columns. As users input data via a web app, the number of rows will dynamicall ...

AngularJS: default option not being selected in dropdown menus

I need assistance with a dropdown list issue. See the code snippet below: My Controller (function(angular) { 'use strict'; angular.module('ngrepeatSelect', []) .controller('ExampleController', ['$scope', functi ...

What is the best method to organize HTML tables in Knockout by utilizing a Breeze navigation property?

Currently, I am utilizing Breeze.js to manage my data model within Knockout.js. This involves a simple view model with an adapter library for handling sorting tables on entity properties. The tables are sorted using tablesorter, along with a knockout bindi ...

Leverage the power of the MEAN stack with Angular 2 to seamlessly retrieve data from multiple APIs

Using angular2, nodejs, expressjs, and mongodb for development. I need all APIs to fetch data and display it on an HTML page. Below is the code snippet from my .ts file. view image description here All APIs have been tested and are s ...

Is there a way to turn off eslint's no-promise-executor-return rule?

Can the eslint rule 'no-promise-executor-return' be disabled? my .eslintrc file { "env": { "es6": true, "node": true }, "extends": [ "airbnb-base" ], "globals": { "de ...

Bootstrap 4 or ngBootstrap: A Comparison

I have a couple of inquiries: Firstly, I am wondering if ngBootstrap is compatible with Angular 4. While I've seen instances on Google where individuals have successfully used Angular 4 with ngBootstrap, the official site mentions dependencies on Ang ...

utilize Java version specifically designed for integrating with Angular framework and SOAP web services

One question I've been pondering: we currently have a project built on Java 6 and GWT, but we're considering migrating to Angular (using SOAP web services). Will Java 6 be compatible with Angular for the backend, or will we need to upgrade to Jav ...

Tips for dividing by a large number

I am currently attempting the following: const numerator = 268435456; const denominator = 2 ** 64; const decimalFraction = numerator / denominator; In order to achieve this, I have experimented with utilizing the code provided in this link: : const rawVal ...

Receiving data through multiple ajax calls nested within another ajax call

Hello everyone, I am diving into the world of AJAX/jQuery and would appreciate your patience as I try to navigate through it. I have an interesting challenge ahead so let's see how we can tackle it together ...

In ReactJs, what is the best way to load a new component when a button is clicked?

In ReactJs, I have developed a main component known as MainPage using Material-UI. import React from 'react'; import Grid from '@material-ui/core/Grid'; import Button from '@material-ui/core/Button'; import CssBaseline from & ...

The only information returned from calling mongoose's Model.save() method are the fields { _id, __

I've encountered a problem even though I believe I'm following all the right steps. I'm attempting to save an item from a form into my mongodb collection using mongoose. This is what my schema looks like: // stationmodel.js export const Sta ...

How can we exclude fields from JSON.stringify in type-graphql entities?

Utilizing https://github.com/MichalLytek/type-graphql for crafting our graphql schema has posed a challenge. When we serialize the TypeScript entity object, it does not adhere to the field annotations in our GQL entities, resulting in unwanted data leakage ...

"Utilize PHP to access an object's properties in a manner similar to an array

Consider the JSON object presented below: $json = '{ "Name": "Peter", "countries": { "France": { "A": "1", "B": "2" }, "Germany": { "A": "10", "B": "20" }, .... } }'; I am looking for a way to ...

Ways to conceal the scroll bar upon the initial loading of a webpage

Recently, I created a single-page website consisting of 4 sections. The client has specific requirements that need to be fulfilled: The scrollbar should not be visible when the page loads. Once the user starts scrolling past the second section, the scrol ...

Error: Unable to locate namespace 'google' in TypeScript

I am currently working on an angular-cli project. ~root~/src/typings.json { "globalDevDependencies": { "angular-protractor": "registry:dt/angular-protractor#1.5.0+20160425143459", "jasmine": "registry:dt/jasmine#2.2.0+20160621224255", "sele ...

Updating or deleting query strings using JavaScript

My URL is structured as follows: http://127.0.0.1:8000/dashboard/post?page=2&order=title I am seeking a way to eliminate the query string ?page={number} or &page={number} Due to my limited knowledge of regular expressions, I am wondering if there ...

retrieving the parent of the a tag from a jquery form

When using the jQuery code below: $('#trade-offer form').on("submit", function(event) { event.preventDefault(); var stock = $(this).closest('.allloopedover'); console.log(stock); return; $.ajax({ url: ajaxur ...