Utilizing Observable for Navbar concealment in Angular 2

Here's my dilemma:

I have a navbar in my app.component that I want to hide before someone logs in by setting a boolean variable to true using ngIf.

app.component.html:

<navbar *ngIf="_userLoggedIn === true" ></navbar>
<router-outlet></router-outlet>

After researching and reading through various questions, I believe using Observables is the way to go. However, I'm struggling to implement them effectively. My idea is to use an Observable in a global service to share a variable that a child component can access and modify, allowing the app.component to subscribe to that variable and change _userLoggedIn to true (initially false) when the observable is set to true.

I am using my login.component with the angular2 router, so it is displayed in the <router-outlet>.

{
        path: '/login',
        name: 'Login',
        component: LoginComponent,
        useAsDefault: true
    },

In that component, I want to set the variable to true after a successful login so that it changes in app.component and the Navbar is shown. If you need more code, please let me know.

It would be greatly appreciated if anyone could help me with this issue or offer an alternative solution.

Answer №1

I encountered a similar issue and sought assistance on this platform: How to modify a component on specific routes in Angular2

The crux of the problem lies in the limitation of using @CanActivate or onActivate exclusively. These utilities can only be applied to Components that are routed TO, not FROM. If, for instance, your app.component contains a topbar or sidebar with the router-outlet nested within its template, accessing route data becomes challenging.

Hence, a viable solution involves extending the default router-outlet and incorporating your logic there.

By implementing a @RouteConfig like the one below:

@RouteConfig([
{
    path: '/login',
    name: 'Login',
    component: LoginComponent,
    data: {
        hideTopbar: true,
        hideSidebar: true
    }
},

and crafting a template for your app.component as follows:

<div class="topbar" *ngIf="showTopbar">...</div>
<extended-router-outlet></extended-router-outlet>

You can manage this in your app.component class:

export class AppComponent {
    showTopbar:boolean;
    showSidebar:boolean;

    constructor(private _routingEventService:RoutingEventService) {
        this._routingEventService.onRouteChanged().subscribe(routeData => {
            this.showTopbar = !routeData.hideTopbar;
            this.showSidebar = !routeData.hideSidebar;
        });
    }
}

utilizing a routed event service as described in the linked answer above:

@Injectable()
export class RoutingEventService {
    private _eventEmitter: EventEmitter<any> = new EventEmitter();

    routeIsChanging(obj:any) {
        this._eventEmitter.emit(obj);
    }

    onRouteChanged() {
        return this._eventEmitter;
    }
}

Subsequently, create your new router-outlet directive as follows:

@Directive({
    selector: 'extended-router-outlet'
})

export class ExtendedRouterOutlet extends RouterOutlet {
    private parentRouter:Router;

    constructor( _elementRef: ElementRef,
                 _loader: DynamicComponentLoader,
                 _parentRouter: Router,
                 @Attribute('name') nameAttr: string,
                 private _routingEventService:RoutingEventService ) {
        super(_elementRef, _loader, _parentRouter, nameAttr);
        this.parentRouter = _parentRouter;
    }

    activate(nextInstruction: ComponentInstruction): Promise<any> {
        this._routingEventService.routeIsChanging({
           name: nextInstruction.routeName,
           hideTopbar: nextInstruction.routeData.data['hideTopbar'],
           hideSidebar: nextInstruction.routeData.data['hideSidebar']
        });
        return super.activate(nextInstruction);
   }
}

This approach allows for the handling of various route-specific logic, such as authentication or role checks, as elaborated in my response to a related query:

Populating form fields after receiving HTTP response in Angular2

Hopefully, this explanation proves beneficial.

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 testing an endpoint with Jasmine/Karma?

Within one of my components, there is a method that makes a call to an endpoint in the following manner... private async getRolesAsync(): Promise<void> { const roles = await this.http.get<any>('https://sample-endpoint.com').toProm ...

Can storing JWT in the windows object be considered a secure method for easy retrieval when required?

I have received an access token (JWT) in the URL. For example: . Is it secure to save this token in the window object? For instance: window.jwt = Token If so, how can it be utilized (extracting the JWT from the Window object and carrying out subsequent ...

What could be causing the CSS loader in webpack to malfunction?

I am currently working on implementing the toy example mentioned in the css-loader documentation which can be found at https://github.com/webpack-contrib/css-loader Additionally, I have also followed a basic guide that recommends similar steps: https://cs ...

Typescript libraries built specifically for unique custom classes

I am currently exploring the most effective method for creating a class library in Typescript and deploying it to NPM along with a definitions file. The classes within the library serve as models that are utilized by multiple RESTful services. Some of the ...

What are some effective methods for troubleshooting Vue.js computed properties and templates?

I am facing challenges with debugging in Vue.js, especially when it comes to debugging computed properties or data values in templates. Currently, I am using the IIFE method for debugging as shown in : <h2 dir="auto"> {{(function(){debugger;let ...

By default in Angular 2, radio buttons will not be checked

Here is the HTML code snippet : <div class="form-group"> <div class="form-text">Question about Email and Phone Details?</div> <div> <input type="radio" value="1" [formControl]="si ...

I'm having trouble getting systemjs to properly connect and download my latest module

Recently, I developed an Angular module that is being downloaded via npm as a private node module in our company registry. Despite setting the default extension to js, my systemjs keeps searching for it in my current directory with any extension. ...

Utilize a personalized useFetch hook in React.js to transmit a POST request and obtain a response

I recently came across a great resource on this website that provided the logic for a useFetch hook. My goal is simple - I want to send a post request and then map the response into a specific type. While this seems like it should be straightforward, I&apo ...

Transferring an Image File from Angular 8 to a Spring Boot Application

Having trouble sending a file from my Angular 8 app to my Spring Boot server. I've tried using MultiPartFile and HttpServletRequest in Spring, among other methods, with no luck. I'm hoping someone can provide guidance on how to successfully retr ...

In Angular 8, a communication service facilitates interaction between parents and children

Using a Sharing service, I am able to pass data from my app component to the router-outlet render component. While I have been successful in passing strings and other data, I am now looking for a way to retrieve data from an API and share it with a compone ...

Issue encountered when trying to pass a string into URLSearchParams

const sortString = req.query.sort as string const params = Object.fromEntries(new URLSearchParams(sortString)) Upon moving to the implementation phase, I encountered: declare var URLSearchParams: { prototype: URLSearchParams; new(init?: string[][] ...

Formulate a Generic Type using an Enum

I'm currently working on a project that involves creating a generic Type using enums. Enum export enum OverviewSections { ALL = 'all', SCORE = 'score_breakdown', PERFORMANCE = 'performance_over_time', ENGAGEMENT ...

Establishing a connection pathway for communication among components in Angular

I am faced with a situation where I have two components, CompA and CompA5, that are 3 or 4 levels apart. I need to establish a means of communication between these components. For instance, I want component CompA to send an event to CompA5, receive some d ...

Guide on utilizing a module in TypeScript with array syntax

import http from "http"; import https from "https"; const protocol = (options.port === 443 ? "https" : "http"); const req = [protocol].request(options, (res) => { console.log(res.statusCode); }); error TS2339 ...

Guide to deploying Angular application on a weblogic server using a WAR/EAR file

I am facing difficulties deploying an Angular application on a WeblogicApplication server. My current approach is not yielding successful results: This is what I have done: 1) Built my Angular application using exec-maven-plugin and placed the result i ...

How can I effectively address process.on test in TypeScript Mocha Testing with the help of a Sinon Spy?

I need to conduct a test on the warning process for my Typescript project. The specific code that I am attempting to test is shown below: process.on('warning', (warning) => { LoggingService.info('Warning, Message: ' + warning.mes ...

Creating a unique Elastic IP address for a single EC2 instance with the AWS CDK

I'm having an issue with my AWS CDK Stack where multiple Elastic IPs are being created for each public subnet in my VPC instead of just one. I only want one Elastic IP to be associated with a single EC2 instance. My simplified code snippet is as foll ...

Storing redux dispatch action using the useRef hook in Typescript

Currently, I am attempting to store the redux action dispatch in a React reference using useRef. My goal is to be able to utilize it for aborting actions when a specific button is clicked. Unfortunately, I am facing challenges with assigning the correct ty ...

The matInput directive is experiencing issues when used in a module that is loaded laz

After implementing a lazy loading module, I encountered an issue where elements like matInput were not displaying correctly. Even though the MatInputModule was imported in the module as expected: const routes = [ {path: '', component: AddPlace ...

Finding a solution to the error message "CORS policy: Response to preflight request doesn't pass access control check" without resorting to browser plugins

While I realize this question may have been asked before and is considered a duplicate, I have tried the suggested solutions without success. So please take a moment to review my question and offer some assistance. My goal is to call a GET method at the U ...