Ways to generate an observable within a subscribe method

I'm struggling to create an observable that retrieves a certain value from a subscriber. Here's the code I've been working on:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<boolean> {
    // get route to be activated
    this.routeToActivate = route.routeConfig.path;

    // retrieve user access levels        
    return this._firebase.isUserAdmin          <-- returns Subscription, not Observable
        .map(user => user.access_level)
        .subscribe( access => {
           // Need to return an observable here
        });
}

I've been having trouble finding reliable resources on observables in Angular 2 to guide me. Any assistance with this would be greatly appreciated!

UPDATE -> Working Version

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<boolean> {
            // get route to be activated
            this.routeToActivate = route.routeConfig.path;

            // retrieve user access levels        
            return this._firebase.isUserAdmin
                .map(user => {
                    let accessLevel = user.access_level;

                    if (accessLevel === 'admin' ) {
                        return true;
                    }

                }).first();
        }

Answer №1

In order to efficiently handle observables in Angular, it is important to understand the difference between using `map` and `subscribe`. When you use `map`, an `Observable` is returned rather than returning the observable directly from `subscribe`.

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<boolean> {
    // Determine the route to activate
    this.routeToActivate = route.routeConfig.path;

    // Obtain user access levels
    return this._firebase.isUserAdminObservable
        .map(user => {
            // Perform actions here based on user access level
            // user.access_level;
            return true;
         })
        .first(); // Ensure that the observable completes after the first event (often necessary for canActivate)
        // Note that 'first' needs to be imported similarly to 'map'
}

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<boolean> {
    // Determine the route to activate
    this.routeToActivate = route.routeConfig.path;

    let subject = new Subject();
    
    // Obtain user access levels        
    this._firebase.isUserAdminObservable
        .map(user => {
            let accessLevel = user.access_level; 
            if (accessLevel === 'admin') { 
                subject.emit(true); 
                subject.complete();
            } 
            return user;
        });
        
     return subject;
}

Answer №2

If you're looking to subscribe to an observable, manipulate the outcome, and then return the modified result within the same subscription, follow these steps:

function xyz(): Observable<any> { 
    const data = fetchDataAndReturnObservable().pipe(map(response => {
          // Implement any desired processing on the response //
          return response; // Return the processed result.
       }
    ))
   return data;
}

Answer №3

Is it possible to utilize the pipe function along with map from the

import { map } from 'rxjs/operators';
statement?

import { map } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class SearchHostService {
  constructor(private readonly http: HttpClient) {}

  searchForHosts(searchString: string): Observable<Employee[]> {
    return this.http
      .get<Employee[]>('./assets/host-users.json')
      .pipe(
        map(employees =>
          employees.filter(({ displayName }) =>
            displayName.toLowerCase().startsWith(searchString),
          ),
        ),
      );
  }
}

Answer №4

To transform the Observable object into a promise, you can utilize the toPromise method. Below is an example of how this code can be implemented:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Promise<boolean> {
        // Obtain the route to activate
        this.routeToActivate = route.routeConfig.path;

        // Retrieve user access levels        
        return this._firebase.isUserAdmin
            .map(user => {
                return (user.access_level === 'admin');
            }).toPromise();
    }

Answer №5

If you're looking to filter with a predicate and apply a projection function for the first element, this code snippet has got you covered.

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<boolean> {
    this.routeToActivate = route.routeConfig.path;      
    return this._firebase.isUserAdminObservable
        .first((_, index) => index === 0, user => {
           // Add your logic here
           // user.access_level;
           return true;
         })
}

Read more about the first operator

Answer №6

To trigger an event based on the access level, you can create a new observable.

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<boolean> {
    // Retrieve route to activate
    this.routeToActivate = route.routeConfig.path;

    // Obtain user access levels
    return new Observable(subscriber=>{
       this._firebase.isUserAdmin
        .map(user => user.access_level)
        .subscribe(access => {
           // Create and return an observable based on logic conditions
           // Modify your logic here...
           return access === XXX ? subscriber.next(true) : subscriber.next(false);
        }, err => subscriber.error());
    })
}

For more information, visit: https://rxjs-dev.firebaseapp.com/guide/observable

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

Mistakes found in the TypeScript-Angular code produced by Swagger Codegen

I utilized Swagger CodeGen to automatically create the API client required for an Angular5 application. The code generation was done through a maven plugin configured as shown below: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http:/ ...

Tips for preventing flickering caused by set Interval in angular 2+

Displaying dynamic latitude and longitude data on Google Maps while using setInterval() function. Code snippet below: this.timer = setInterval(()=>{this.getMapData();},30000); An issue arises where the map flickers when updating the data with this.get ...

The delete() method in AngularFirestoreDocument does not actually remove documents from the database

My function for removing a document in Firestore doesn't seem to be functioning correctly. I've double-checked the document ID it receives, but that doesn't appear to be the issue. I even tried removing the return statement before the delet ...

The necessity for one type argument is apparent in a generic type, particularly when it is divided into a distinct type

I have a simple scenario that resembles the following and is functioning perfectly: export interface CustomState { someBool: boolean; status: string; } function checkStateDifference<K extends keyof CustomState>(props: { stateKey: K, value: Custo ...

I recently downloaded a project from Github, but I'm encountering issues as the npm start command is not

This is the latest update for my project: https://github.com/rietesh/Hyperledgerfabric-Airline-App.git Upon running npm start, the following error message is displayed: The serve command should only be executed within an Angular project, but no project de ...

Adding services to an Angular class instance for dependency injection

When attempting to utilize an instance of a class within a static property of another class, I encountered the following issue: class MyHelper { private authService: AuthService; constructor() { this.authService = inject(AuthService); this ...

Internal variable via router

The Back button on my main component is not always visible, depending on the child component. I have attempted to use a local variable with no success. In my parent app.component.html file, I have included the following: <button *ngIf="child.goBackUrl ...

What is the best way to determine the type of `rootReducer`?

My project is set up with a combination of React, Redux, Immutable.js, and TypeScript. As I worked on implementing it, I made an effort to declare types wherever possible which led me to discover an interesting issue. A code example illustrating the proble ...

Issue of false positive with no-shadow when defining a TypeScript enum within a JHipster application

How can I effectively use an enum in my application? export const enum typeEnum { TVY = 'TVY', USER = 'USER', } During the npm run webpack:build process, I encountered the following error : 12:111 error 'typeEnum' is ...

Tips for updating a key value in a response using Angular HTTP

After receiving a JSON response, I found that the ImagePath URLs are redirecting to different locations when combined with the domain name. [{ "ImagePath": "/folder/images/products/1.jpg", "LanguageId": 2, ...

mat-select-country - encountering difficulty in defining default selection

I have implemented the mat-select-country component to display a list of countries and allow users to select one. <mat-select-country appearance="outline" country="IN" [itemsLoadSize]="5" (onCountrySelected)=&q ...

I am able to view the node-express server response, but unfortunately I am unable to effectively utilize it within my Angular2 promise

https://i.stack.imgur.com/d3Kqu.jpghttps://i.stack.imgur.com/XMtPr.jpgAfter receiving the object from the server response, I can view it in the network tab of Google Chrome Dev Tools. module.exports = (req, res) => { var obj = { name: "Thabo", ...

What is the best way to customize the primary Button style in Bootstrap?

Would you like the background-color to change when clicking on the radioButton? .btn-primary:hover, .btn-primary:active, .btn-primary:visited, .btn-primary:focus { background-color: black !important; color: white !important; } .btn-primary { colo ...

Angular 2 Component remains persistent when accessed through parameterized routes

Here is my test route with parameter T1: { path: 'Test/:T1', component: TestComponent }, After routing from 'Test/1' to 'Test/2', I noticed that my TestComponent does not reinitialize. Could this be a problem with th ...

What is the best way to retrieve the `any` type when utilizing the `keyof` keyword?

I am struggling to articulate this question properly, so please refer to the code below interface TestParams<T> { order?: keyof T attr1?: number attr2?: string } async function Test<T = any>(_obj: TestParams<T>): Promise<T> { ...

Determining if an object aligns with a specific type in Typescript

Hey there, I've got a little dilemma. Imagine I have a type called A: type A = { prop1: string, prop2: { prop3: string } } Now, let's say I'm getting a JSON object from an outside service and I need to check if that JSO ...

Automatically collapse a expanded row using a button programmatically

I utilized this particular model to construct a table featuring expanded rows: https://stackblitz.com/edit/angular-material2-expandable-rows-filter-pagination-sorting?file=app%2Fcdk-detail-row.directive.ts The issue I'm encountering is the inability ...

Is there a way to extract only the desired array object from a post API response using Angular's filtering mechanism?

I'm utilizing the getSearchBank() post API and receiving this particular response from it. This API provides me with a list of all banks stored in the database. (8) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}] 0: {bankId: '616c07ca9d ...

"Utilizing the range option in a NodeJS request proves ineffective when attempting to stream HTML5

I have set up a nodejs request to serve videos with range support. The backend code looks like this: import { createReadStream, statSync } from 'fs'; const stats = statSync(path); const range = request.headers.range; const parts = ra ...

Combine all Angular Material Styles into a single CSS file rather than dynamically loading each style at runtime

I have encountered an issue in my Angular 8 Application where multiple style tags are dynamically generated at runtime for Angular Material. To address this, I am looking to add a CSP attribute to all my style tags after the build process is completed. To ...