Invoke the subscribe function within the encompassing parent function

In crafting a versatile method, I have devised the following code snippet:

fetchArticle(loading: Loading): void {
    this.articleService.getArticleById(this.data.definition.id)
      .map((response: any) => response.json())
      .subscribe((response: any) => {
        if (response.definition.is_purchased) {
          //additional instructions
          } else {
            //more instructions
          }
          loading.dismiss();
        } else {
           loading.dismiss();
        }
      }, () => { 
          loading.dismiss(); 
      });
  }

The method invoking this function looks like the following:

 myCallerFunction() {
     const loading = this.loader.create({
      content: 'loading...'
    });
    loading.present();

    this.fetchArticle(loading); //Can I place `loading.dismiss()` here? 
    }

To streamline the process, I am seeking advice on how to eliminate the loading parameter from the generic fetchArticle() method and move it within the parent function (myCallerFunction()) after resolving the subscription. Can you suggest a way to achieve this?

Answer №1

When dealing with an observable that terminates at a higher level, you must ensure to return an observable that can be accessed by the higher-level function.

One way to write this is:

getArticleById(loading: Loading) {
    const articles$ = this.articleService.getArticleById(this.data.definition.id)
      .map((res: any) => res.json());

    article$.subscribe((res: any) => {
        if (res.definition.is_purchased) {
          //more code
          } else {
            //more code
          }
    });

    return article$;  
}

The finally operator comes in handy as it:

Invokes a specified action after the source observable sequence terminates gracefully or exceptionally.

myParentMethod(){
    const loading = this.loader.create({
      content: 'loading...'
    });
    loading.present();

    this.getArticleById().finally(() => loading.dismiss());
}

However, to improve the structure of the code, consider separating the logic for obtaining the observable from handling it. The revised code would look something like this:

getArticleById(): Observable<Article> {
    return this.articleService.getArticleById(this.data.definition.id)
      .map(res => res.json());
}

handleArticle(article) {
    if (article.definition.is_purchased) {
      //more code
    } else {
        //more code
    }
}

myParentMethod(){
    const loading = this.loader.create({
      content: 'loading...'
    });
    const article$ = this.getArticleById();

    loading.present();

    article$
      .finally(() => loading.dismiss())
      .subscribe(article => this.handleArticle(article));
}

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 with implementing MUI Style Tag in conjunction with styled-components and Typescript

I have created a custom SelectType component using Styled Components, which looks like this: import Select from '@mui/material/Select'; export const SelectType = styled(Select)` width:100%; border:2px solid #eaeaef; border-radius:8px ...

Is the Kendo Spreadsheet supported in Angular 2?

We are interested in knowing if future releases of Angular2 will include Kendo Spreadsheet or the ability to export data to Excel for the grid. We currently use the Angular1 version and would like to upgrade, so having these features available in Angular2 ...

Steps for deactivating a button based on the list's size

I am trying to implement a feature where the user can select only one tag. Once the user has added a tag to the list, I want the button to be disabled. My approach was to disable the button if the length of the list is greater than 0, but it doesn't s ...

Developing interactive checkboxes for individual rows through React.js

Within a form, I have rows containing two inputs each. Upon clicking "add", a new row is created. For the second row onwards, by clicking "add" a checkbox labeled 1 should be added to indicate dependency on the previous row. In addition, for the third row, ...

Learn how to properly convert a string into a valid URL using the Next JS router when pushing pages

I'm dealing with a string that looks like this: /dashboard/products/:id. My goal is to utilize Next Js's router to navigate to that URL and replace the placeholder :id with an actual id. Here's the code I've written: {products.map(prod ...

Tips for keeping the main section from scrolling while scrolling through the side navigation

Within my Angular application, I have implemented a sidenav and a main section. My desired behavior is to prevent any scrolling in the main section while I am scrolling in the sidenav, similar to the functionality seen on the Angular Material Design docume ...

Using Typescript and React to assign an array object to state

Here is the situation: const [state, setState] = useState({ menuCatalog: true, menuCommon: true, fetched_data: [] }); An example of data I am trying to set to the state property "fetched_data" looks like this: [{"id": 1, "name": "some_name", " ...

Implementing the MVC pattern in the app.js file for a Node.js and Express web application

After completing several tutorials on nodejs, mongodb, and express, I have gained a solid understanding of the basics such as: The main controller file being app.js. Third party modules stored in their designated node_modules directory. Template files pl ...

When utilizing the React onclick function, it generates an increase in state values rather than modifying

I'm currently working on a function that changes the state property, "changedMarkup", when a button is clicked. Initialization constructor() { super(); this.state = { value: 0, changedMarkup: 0 }; } Render Function render() ...

In Javascript, the color can be changed by clicking on an object, and the color

Looking for help with my current HTML code: <li><a href="index.php" id="1" onclick="document.getElementById('1').style.background = '#8B4513';">Weblog</a></li> The color changes while clicking, but when the lin ...

JavaScript: A guide to finding CSS properties within a string

Checking for CSS Properties in Over 1,000 Sentences Is there a way in Javascript to check sentences against a built-in CSS index? Currently… If I need to search for CSS properties in the sentences below, I have to create an array containing all the CS ...

Typescript: Subscribed information mysteriously disappeared

[ Voting to avoid putting everything inside ngOnit because I need to reuse the API response and model array in multiple functions. Need a way to reuse without cluttering up ngOnInit. I could simply call subscribe repeatedly in each function to solve the p ...

Exploring Next.js' dynamic routes with an alternative URL approach

Currently in the process of transitioning a React project to Next.js, I've encountered a minor issue with Dynamic Routing that doesn't seem to have any readily available solutions online. I have multiple information pages that utilize the same c ...

How to Easily Add GitHub NPM Packages to Your SAPUI5 Web IDE

Looking to integrate an NPM package from Github into SAPUI5 using the WebIde Framework. Package Link: https://github.com/commenthol/date-holidays/blob/master/README.md#usage Primary Issue: Need a file with the library for importing and copying into the W ...

Exploring the power of Vue.js with dynamic HTML elements and utilizing Vue directives within Sweet Alert

new Vue({ el: '#app', data(){ results: [] } }); I need assistance with implementing Vue directives, events, etc. within the markup of a Sweet Alert. The goal is to display an alert using Sweet Alert that include ...

What is the appropriate way to notify Gulp when a task has been completed?

I have been working on developing a gulp plugin that counts the number of files in the stream. Taking inspiration from a helpful thread on Stack Overflow (source), I started implementing the following code: function count() { var count = 0; function ...

The authentication status returned by PassportJS's req.isAuthenticated function consistently indicates as false

I have successfully implemented login authentication using nodejs/Angular passport middleware. However, I am facing an issue where the passport.deserializeUser function is not being called when I try to retrieve the login username through req.authenticat ...

Exploring Vue Component Features through Conditional Display

I am working with a vue component called <PlanView/>. In my code, I am rendering this component conditionally: <div v-if="show_plan" id="mainplan"> <PlanView/> </div> <div class="icon" v-else> ...

Promise rejection not handled: The play() function was unsuccessful as it requires the user to interact with the document beforehand

After upgrading my application from Angular 10 to 11, I encountered an error while running unit tests. The error causes the tests to terminate, but strangely, sometimes they run without any issues. Does anyone have suggestions on how to resolve this issue? ...

Modify path and refresh display upon ajax call to node server

Recently, I made the decision to utilize a Node server as a proxy for making API calls to third-party public APIs from my front end. After successfully sending a request to my Node endpoint and then to the third-party API, I received the expected response. ...