2

I've a component HomeComponent and I have two services : AnimalService and DogService

DogService extends AnimalService like that :

@Injectable({providedIn: 'root'})
export class AnimalService {
    constructor() {}
    move(): any {
        console.log('move animal');
    }
}

@Injectable({providedIn: 'root'})
export class DogService extends AnimalService {
    constructor() {
        super();
    }
    scream(): any {
        console.log('il crie');
    }
}

And then I want to use it by calling scream function inside my component :

    @Component({
        selector: 'jhi-home',
        templateUrl: './home.component.html',
        styleUrls: ['home.scss']
    })
    export class HomeComponent implements OnInit {

        constructor(private dogService: DogService) {}

        ngOnInit() {
            this.dogService.scream(); // the error here : scream is not a function
        }
    }

But I have the following error :

this.dogService.scream is not a function

Maybe there is a subtility with angular, becaus of Injectable or something like that, I know that the constructor of DogService is not called, si my webbrowser undertands that it's an AnimalService. it's not the case if I do a dogService = New DogService instead of declaring it inside the constructor. But I don't understand why.

Any ideas ?

1
  • Have you tried registering your services in the module instead of providedIn flag? Commented Aug 1, 2018 at 21:46

1 Answer 1

1

The problem is the annotation in your SuperClass. Don't annotate AnimalService. It must be an abstract simple class.

export abstract class AnimalService {
    constructor() {}
    move(): any {
        console.log('move animal');
    }
}

@Injectable({providedIn: 'root'})
export class DogService extends AnimalService {
    constructor() {
        super();
    }
    scream(): any {
        console.log('il crie');
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

I think the OP intention is to be able to use the superclass on its own too. If it is not annotated then it could not be used as a service. Maybe he/she needs to rethink the design if this is not possible.
I agree. What I intended to show was, that inheritance among services only works if only one class gets the Injectable annotation and this has to be the inheriting class.
In that case, make AnimalService an abstract class (without the @Injectable), and create a separate implementation of AnimalService (with the @Injectable). That way, DogService can still extend the abstract, and a separate injectable instance can be created
@Lynx Thanks for your answer. Yes I would like to continue to use AnimalService. So finally what I did is the following : I duplicated AnimalService in an abstract class AbstractAnimalService and I extended DogService on that. In that way I can continue to use AnimalService and if I want use DogService with all features (both implemented in the abstract class and the DogService himself). Don't hesitate to tell me if it's a good practice or not !
Great to hear that it worked for you. :-) Yes, your approach with the abstract class that gets used by AnimalService and DogService is a good one. Really well done.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.