JoseTurron
JoseTurron

Reputation: 243

Setting a timeout in multiple components with service in angular

I'm trying to set a timeout within a set of components using angular service. I tried to follow the materials I found online but I'm a bit stuck. I already created the timeout.service.ts file and put the code there but I get multiple errors. I need help in getting this right. The timeout worked fine when it was in the component itself but I want to work according to the DRY methodology. Thanks for the support in solving this!

STACKBLITZ: https://stackblitz.com/edit/flight-date-picker-with-service

COMPONENT.TS:

    import { Component, OnInit } from '@angular/core';7
    import { Router, RouterLink } from '@angular/router';
    import { HostListener } from '@angular/core'
    import { TimeoutService } from '../timeout.service';
    
    @Component({
      selector: 'app-chooseflight',
      templateUrl: './chooseflight.component.html',
      styleUrls: ['./chooseflight.component.scss'],
      providers: [TimeoutService]
    })
    export class ChooseflightComponent implements OnInit {
      constructor(private router: Router, timeoutService: TimeoutService) {
        this.showStorage = localStorage.getItem("flightdetails") || {};
      }
    
    
      ngOnInit() {
        this.resetTimer();
      }
      // public time: any;

      // @HostListener('document:mousemove')
      // @HostListener('document:keypress')
      // @HostListener('document:click')
      // @HostListener('document:wheel')
      // resetTimer() {
      //   clearTimeout(this.time);
      //   this.time = setTimeout(() => {
      //   localStorage.removeItem("flightdetails");
      //   console.log("Local storage will now be deleted");
      //   this.router.navigate(["/chooseflight"]);
      //   }, 180000);
      // }

The commented parts were moved to the service file:

    export class TimeoutService {
      public time: number;
      
      console.log("TimeoutService Działa!");
      @HostListener('document:mousemove')
      @HostListener('document:keypress')
      @HostListener('document:click')
      @HostListener('document:wheel')
      resetTimer() {
        clearTimeout(this.time);
        this.time = setTimeout(() => {
        localStorage.removeItem("flightdetails");
        console.log("Local storage will now be deleted");
        this.router.navigate(["/chooseflight"]);
        }, 180000);
      }
    }

Upvotes: 0

Views: 1601

Answers (1)

Jeremy
Jeremy

Reputation: 1298

You are on the right track. However, when you copied the code to the service you missed a few important steps:

  1. Import everything you need in the service and use a constructor as you were in the component
  2. Set up a service as a provider in the app.module

1 Import everything you need in the service and use a constructor as you were in the component

In the service, you only have the @HostListener without the proper imports. At the top of the service.ts file, I added the following:

import { Router } from "@angular/router";
import { HostListener, Injectable} from "@angular/core";


@Injectable({
  providedIn: 'root',
})

See that I also added the @Injectable({}). You can learn more about this here, here or here. The @Injectable() is an essential ingredient in every Angular service definition.

Now inside of the class, you need to add a constructor since you plan on using a router:

constructor(private router: Router) {  }

as a sidenote,, you may need to change where the router.navigate is pointing to since you're in a different file, so make sure to check this.

2 Set up a service as a provider in the app.module

Any time you use a service in an app, you need to set it up as a provider in the app.module (or whichever module you are using for the app). This is a quick fix. In your app.module.ts file, at the top with the other imports, add the following:

import { TimeoutService } from './timeout.service';` 

then, in the @NgModule({...}), add a providers: [] array to hold all your services.

@NgModule({
  imports:      ...
  ...
  providers: [TimeoutService]
})

This should now be set up as you had it before in the component. Please let me know if you have any questions. Here is the updated StackBlitz

Upvotes: 1

Related Questions