Implementing asynchronous data sharing within an Angular 2 service

I seem to be facing a challenge that I can't quite figure out. My goal is to share data asynchronously between components that I receive from a server.

Here is an example of what my service code looks like:

import {Injectable} from 'angular2/core';
import {ApiService} from './api.service';

@Injectable()
export class UserService {
    private user: Object

    constructor(private _api: ApiService) {}

    getUser(user) {
        return this.user
    }

    setUser(slug) {
        return Promise.resolve(this._api.GET('users/' + slug + '/?slug=true').subscribe(
            data => { this.user = data.json; return data.json; },
            (err)=>console.log(err)
         ))
    }
}

Due to the asynchronous nature of the process, I need to use a Promise for the response. However, the promised response seems to return the subscribe object instead of the expected data.json.

The scenario involves a profile page with nested routes, where passing data to routed components is not feasible. One of these routed components is "Posts," and after loading the profile, it should begin fetching posts OF THE CURRENT USER IN THE SERVICE.

Here's what needs to happen:

  1. User navigates to their profile.
  2. Service calls setUser('foo'), displays profile page upon response.
  3. Fetches the user's posts into the Posts component using the service's getUser()

This is how the API service is structured:

import {Injectable} from 'angular2/core';
import {Http, Response, RequestOptions, Headers, Request, RequestMethod} from 'angular2/http';
import {GlobalService} from '../app.service';
import 'rxjs/Rx';


@Injectable()
export class ApiService {
    constructor(private http: Http) {}

    apiURL = 'http://localhost:8000/api/';
    assetURL = 'http://localhost:8000/media/';

    GET(url) {
        var headers = new Headers(), authtoken = localStorage.getItem('authtoken');
        headers.append("Content-Type", 'application/json');

        if (authtoken) {
        headers.append("Authorization", 'Token ' + authtoken)
        }
        headers.append("Accept", 'application/json');

        var requestoptions = new RequestOptions({
            method: RequestMethod.Get,
            url: this.apiURL + url,
            headers: headers
        })

        return this.http.request(new Request(requestoptions))
        .map((res: Response) => {
            if (res) {
                return { status: res.status, json: res.json() }
            }
        });
    }
}

Please excuse any confusion in my query as I am still learning Angular 2 and haven't found a definitive solution online.

Answer №1

To ensure a promise is returned, you can implement the following method:

setUser(slug) {
    return new Promise((resolve, reject) => {
      this._api.GET('users/' + slug + '/?slug=true').subscribe(
        data => {
          this.user = data.json;
          resolve(data.json);
        },
        (err) => {
          console.log(err);
          reject(err);
        }
     ))
}

Be sure to properly handle the subscription to guarantee the correct resolution of data.

Answer №2

If you are in need of a Promise, simply utilize the toPromise method

import {toPromise} from 'rxjs/operator/toPromise'

...

   setNewUser(username) {
        return this._api.GET('users/' + username + '/?username=true')
        .map(
            data => { this.newUser = data.json; return data.json; }
         )
         .toPromise()
         .catch(err)=>console.log(err));
    }

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

What are the steps to enable readonly or disabled functionality in Ionic 2?

Trying to make a field readonly or disabled in an ionic2 form: <ion-item> <ion-label fixed>Category <ion-icon name="ios-arrow-forward"></ion-icon></ion-label> <ion-input type="text" [disabled]="false" id="category_ ...

"Upon invoking the services provider in Ionic 2, an unexpected undefined value was

I encountered an issue while setting a value in the constructor of my page's constructor class. I made a call to the provider to fetch data. Within the service call, I was able to retrieve the data successfully. However, when I tried to access my vari ...

Data that changes dynamically on a chart

When making a rest call to fetch data, I aim to populate the pieChartData with the obtained information. However, I am facing difficulties in achieving this task. Can someone guide me on how to accomplish this? import { Component, OnInit} from '@angu ...

A deep dive into TypeScript: enhancing a type by adding mandatory and optional fields

In this scenario, we encounter a simple case that functions well individually but encounters issues when integrated into a larger structure. The rule is that if scrollToItem is specified, then getRowId becomes mandatory. Otherwise, getRowId remains option ...

Aframe's a-assets feature experiencing issues when loading dynamic data through Angular 2

Since there is no fixed number of assets that need to be loaded from the server, I am utilizing Angular 2 templates to dynamically create assets. Below is a snippet of sample code: <a-assets> <div *ngFor="let scene of floorData.scen ...

Enhancing Apollo Cache Updates using TypeScript null checks

Currently, I am utilizing apollo codgen to automatically generate types for my graphql queries in TypeScript. However, I have noticed that the generated types contain numerous instances of null values, leading to an abundance of if checks throughout my cod ...

Struggling to determine the necessary modules to import in order to successfully integrate Firestore with Angular services

Recently, I developed a simple service with the following structure: @Injectable({ providedIn: "root" }) export class ItemService { private db!: CollectionReference<DocumentData>; constructor(private firestore: Firestore) { this. ...

Perform simple arithmetic operations between a number and a string using Angular within an HTML context

I'm stuck trying to find a straightforward solution to this problem. The array of objects I have contains two values: team.seed: number, team.placement: string In the team.placement, there are simple strings like 7 to indicate 7th place or something ...

`The error "mockResolvedValue is not recognized as a function when using partial mocks in Jest with Typescript

Currently, I am attempting to partially mock a module and customize the return value for the mocked method in specific tests. An error is being thrown by Jest: The error message states: "mockedEDSM.getSystemValue.mockResolvedValue is not a function TypeEr ...

Angular 2+ seems to be failing to detect and update changes in variables within the template

I have a component that includes rendering the user's name from the profile object. The corresponding part of the template looks like this: <button mat-button [matMenuTriggerFor]="userMenu" *ngIf="isAuthenticated()"> {{profile?.name} ...

I am experiencing difficulties with *ngIf in my HTML as it is not functioning properly, however, the ng

I have come across many inquiries related to this issue, but none of them proved helpful for me. Below is my HTML code: <div class="pl-lg-4"> <div *ngIf="isStorySelected; else hi" class="row"> ...

`ng build`: transferring scripts to a subdirectory

When running the command ng build, it exports files to the dist folder like this: index.html main.bundle.js styles.bundle.js ... I would like the scripts to be in a subfolder: *index.html scripts/main.bundle.js scripts/styles.bundle.js ...* ...

Redirecting based on conditions in Angular 2+ with wildcard paths

I have a variety of paths, each corresponding to a specific stage in a wizard. const routes: Routes = [ { path: ':id', component: ParentComponent, children: [ {path: 'step1', component: Step1Component}, {path: ...

What is the best method for retrieving the complete path of a FormControl in Angular versions 4 and above

Is there a way to obtain the complete path of a FormControl in Angular 4+? Below is my reactive form structure: { name: '', address: { city: '', country: '' } } I urgently require the full path o ...

Tips for integrating Excel files with NestJS

I'm in the process of developing a REST API that will utilize a third-party API to retrieve specific status information. The URLs needed for this API are stored in an Excel file, which is a requirement for this use case. My goal is to extract the URLs ...

Is it possible to make the 'keyof' property optional?

Illustrate an interface in the following way interface Properties { apple?: string banana?: string cherry?: string date: string } Executing this code works as expected type Sample1 = { [P in keyof Properties]: Properties[P] } const s1: Sample1 ...

Is it possible for a Node.js/Express server to securely handle all UTF-8 characters?

At the moment, my setup involves a node server running Express that is connected to a PostgreSQL database with UTF-8 encoding support. In terms of frontend, I'm using Angular which has built-in measures for preventing unsafe injection. I am curious i ...

Creating a button spinner in Angular CLI to provide feedback while content is loading

While using Angular Cli, I aim to display a loading spinner or text saying "please wait" until the process is complete. For instance: Get Quotes This code snippet shows the content of quotes.component.html : <div class="btn btn-primary" (click)="onGe ...

I noticed that while my shareService is effectively sending values in Angular 2, I encounter an issue where my other components are displaying default values instead

I'm in the process of developing an application using angular 2. I have a UserService that sends a value to other components indicating whether a user is logged in or not, and it's working correctly in terms of data transmission. The issue I&apos ...

Updating from version 1.8.10 to 2.9.2 and encountering a build error in version 4.6.4

I currently have an angular application that is using typescript version 1.8.10 and everything is running smoothly. However, I am interested in upgrading the typescript version to 2.9.2. After making this change in my package.json file and running npm inst ...