Rxjs subscribe not working when subscribing to Behavior Subject in base class





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















I'm currently using Angular 7.



I'm trying to implement a base http service so I can handle every error and show loading gifs all exactly the same. So I have a base service which all my services extend; as soon as a http request is made, I update my Behavior Subject that the page is loading. I subscribe to this BehaviorSubject in my app.component.ts but it is never triggered in here. Looking online, everyone suggests that my base http service is not a singleton and my app.component.ts is subscribing to a different instance of the base service.



I have created a small example on SlackBlitz here.



When you click the "Change showLoading" button, my subscription seems to work fine in the BaseServiceService class but is never triggered in the app.component?



What am I doing wrong?










share|improve this question


















  • 1





    What you are tyring to achieve is easily done using http interceptors.

    – Davy
    Jan 3 at 14:26








  • 1





    I'd suggest you don't inherit from the base service but instead use / inject the base service in your other services. That way you have access to your base service's functions in all other services and still only use one base service instance that you can subscribe to in your components.

    – fridoo
    Jan 3 at 14:54











  • @Davy excellent suggestion, this is the route I took in the end. Although now I have 2 http interceptors (another for is jwt token interceptor). Is it bad practice to have 2 http interceptors?

    – Viqas
    Jan 3 at 15:02






  • 1





    Nope. Not at all. Having one interceptor that does multiple unrelated things would be bad practice.

    – Davy
    Jan 4 at 6:53


















0















I'm currently using Angular 7.



I'm trying to implement a base http service so I can handle every error and show loading gifs all exactly the same. So I have a base service which all my services extend; as soon as a http request is made, I update my Behavior Subject that the page is loading. I subscribe to this BehaviorSubject in my app.component.ts but it is never triggered in here. Looking online, everyone suggests that my base http service is not a singleton and my app.component.ts is subscribing to a different instance of the base service.



I have created a small example on SlackBlitz here.



When you click the "Change showLoading" button, my subscription seems to work fine in the BaseServiceService class but is never triggered in the app.component?



What am I doing wrong?










share|improve this question


















  • 1





    What you are tyring to achieve is easily done using http interceptors.

    – Davy
    Jan 3 at 14:26








  • 1





    I'd suggest you don't inherit from the base service but instead use / inject the base service in your other services. That way you have access to your base service's functions in all other services and still only use one base service instance that you can subscribe to in your components.

    – fridoo
    Jan 3 at 14:54











  • @Davy excellent suggestion, this is the route I took in the end. Although now I have 2 http interceptors (another for is jwt token interceptor). Is it bad practice to have 2 http interceptors?

    – Viqas
    Jan 3 at 15:02






  • 1





    Nope. Not at all. Having one interceptor that does multiple unrelated things would be bad practice.

    – Davy
    Jan 4 at 6:53














0












0








0








I'm currently using Angular 7.



I'm trying to implement a base http service so I can handle every error and show loading gifs all exactly the same. So I have a base service which all my services extend; as soon as a http request is made, I update my Behavior Subject that the page is loading. I subscribe to this BehaviorSubject in my app.component.ts but it is never triggered in here. Looking online, everyone suggests that my base http service is not a singleton and my app.component.ts is subscribing to a different instance of the base service.



I have created a small example on SlackBlitz here.



When you click the "Change showLoading" button, my subscription seems to work fine in the BaseServiceService class but is never triggered in the app.component?



What am I doing wrong?










share|improve this question














I'm currently using Angular 7.



I'm trying to implement a base http service so I can handle every error and show loading gifs all exactly the same. So I have a base service which all my services extend; as soon as a http request is made, I update my Behavior Subject that the page is loading. I subscribe to this BehaviorSubject in my app.component.ts but it is never triggered in here. Looking online, everyone suggests that my base http service is not a singleton and my app.component.ts is subscribing to a different instance of the base service.



I have created a small example on SlackBlitz here.



When you click the "Change showLoading" button, my subscription seems to work fine in the BaseServiceService class but is never triggered in the app.component?



What am I doing wrong?







angular rxjs






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jan 3 at 10:14









ViqasViqas

764421




764421








  • 1





    What you are tyring to achieve is easily done using http interceptors.

    – Davy
    Jan 3 at 14:26








  • 1





    I'd suggest you don't inherit from the base service but instead use / inject the base service in your other services. That way you have access to your base service's functions in all other services and still only use one base service instance that you can subscribe to in your components.

    – fridoo
    Jan 3 at 14:54











  • @Davy excellent suggestion, this is the route I took in the end. Although now I have 2 http interceptors (another for is jwt token interceptor). Is it bad practice to have 2 http interceptors?

    – Viqas
    Jan 3 at 15:02






  • 1





    Nope. Not at all. Having one interceptor that does multiple unrelated things would be bad practice.

    – Davy
    Jan 4 at 6:53














  • 1





    What you are tyring to achieve is easily done using http interceptors.

    – Davy
    Jan 3 at 14:26








  • 1





    I'd suggest you don't inherit from the base service but instead use / inject the base service in your other services. That way you have access to your base service's functions in all other services and still only use one base service instance that you can subscribe to in your components.

    – fridoo
    Jan 3 at 14:54











  • @Davy excellent suggestion, this is the route I took in the end. Although now I have 2 http interceptors (another for is jwt token interceptor). Is it bad practice to have 2 http interceptors?

    – Viqas
    Jan 3 at 15:02






  • 1





    Nope. Not at all. Having one interceptor that does multiple unrelated things would be bad practice.

    – Davy
    Jan 4 at 6:53








1




1





What you are tyring to achieve is easily done using http interceptors.

– Davy
Jan 3 at 14:26







What you are tyring to achieve is easily done using http interceptors.

– Davy
Jan 3 at 14:26






1




1





I'd suggest you don't inherit from the base service but instead use / inject the base service in your other services. That way you have access to your base service's functions in all other services and still only use one base service instance that you can subscribe to in your components.

– fridoo
Jan 3 at 14:54





I'd suggest you don't inherit from the base service but instead use / inject the base service in your other services. That way you have access to your base service's functions in all other services and still only use one base service instance that you can subscribe to in your components.

– fridoo
Jan 3 at 14:54













@Davy excellent suggestion, this is the route I took in the end. Although now I have 2 http interceptors (another for is jwt token interceptor). Is it bad practice to have 2 http interceptors?

– Viqas
Jan 3 at 15:02





@Davy excellent suggestion, this is the route I took in the end. Although now I have 2 http interceptors (another for is jwt token interceptor). Is it bad practice to have 2 http interceptors?

– Viqas
Jan 3 at 15:02




1




1





Nope. Not at all. Having one interceptor that does multiple unrelated things would be bad practice.

– Davy
Jan 4 at 6:53





Nope. Not at all. Having one interceptor that does multiple unrelated things would be bad practice.

– Davy
Jan 4 at 6:53












2 Answers
2






active

oldest

votes


















1














It's nothing to do with singleton, but suggestions about different instance is correct, I will try to explain step by step.



this two instances (BaseServiceService, FileServiceService) which you injected in app.component.ts constructor are different and are initialized independently, that's why this.fileService.callBase(); wont interact/trigger this.baseService.showLoading BehaviourSubject, if you change this.baseService.showLoading.subscribe(x => console.log('new val: ' + x)); this line with this.fileService.showLoading.subscribe(x => console.log('new val: ' + x)); it will work as you expected, now you can just remove private baseService: BaseServiceService injection from constructor and BaseServiceService from providers: [FileServiceService, BaseServiceService]



----Edited----



I think i get what you intend to do, so I modified your demo. here is link https://stackblitz.com/edit/angular-r2wv24






share|improve this answer


























  • Good explanation, I understand, but I want to use the base service as this is what every other service will be using. I don't want to subscribe to every showLoading property on every service in my app.component.ts, just a single base service.

    – Viqas
    Jan 3 at 11:33



















0














Your FileService class extends the BaseService class, which means both classes will have a property showLoading.



Only your FileService service is called through the callBase() method, which means only the showLoading property from your FileService will be notified of any change.



I changed this line in your app.component.ts to subscribe to the FileService instead of the BaseService and it works as intended.



this.fileService.showLoading.subscribe(x => console.log('new val app: ' + x));


I assume you wanted a kind of abstract service to define your showLoading at a higher level ?






share|improve this answer
























  • Yes I do want an abstract service at a higher level. How can I achieve this with my current scenario?

    – Viqas
    Jan 3 at 11:29











  • I guess not extending BaseService would be the first step, and then having your FileService subscribe to your BaseService inner observable ? There are multiple ways to do what you want, but without the big picture in mind it is quite hard to propose a solution based on a mock example...

    – Alex Beugnet
    Jan 3 at 12:14












Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54020211%2frxjs-subscribe-not-working-when-subscribing-to-behavior-subject-in-base-class%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














It's nothing to do with singleton, but suggestions about different instance is correct, I will try to explain step by step.



this two instances (BaseServiceService, FileServiceService) which you injected in app.component.ts constructor are different and are initialized independently, that's why this.fileService.callBase(); wont interact/trigger this.baseService.showLoading BehaviourSubject, if you change this.baseService.showLoading.subscribe(x => console.log('new val: ' + x)); this line with this.fileService.showLoading.subscribe(x => console.log('new val: ' + x)); it will work as you expected, now you can just remove private baseService: BaseServiceService injection from constructor and BaseServiceService from providers: [FileServiceService, BaseServiceService]



----Edited----



I think i get what you intend to do, so I modified your demo. here is link https://stackblitz.com/edit/angular-r2wv24






share|improve this answer


























  • Good explanation, I understand, but I want to use the base service as this is what every other service will be using. I don't want to subscribe to every showLoading property on every service in my app.component.ts, just a single base service.

    – Viqas
    Jan 3 at 11:33
















1














It's nothing to do with singleton, but suggestions about different instance is correct, I will try to explain step by step.



this two instances (BaseServiceService, FileServiceService) which you injected in app.component.ts constructor are different and are initialized independently, that's why this.fileService.callBase(); wont interact/trigger this.baseService.showLoading BehaviourSubject, if you change this.baseService.showLoading.subscribe(x => console.log('new val: ' + x)); this line with this.fileService.showLoading.subscribe(x => console.log('new val: ' + x)); it will work as you expected, now you can just remove private baseService: BaseServiceService injection from constructor and BaseServiceService from providers: [FileServiceService, BaseServiceService]



----Edited----



I think i get what you intend to do, so I modified your demo. here is link https://stackblitz.com/edit/angular-r2wv24






share|improve this answer


























  • Good explanation, I understand, but I want to use the base service as this is what every other service will be using. I don't want to subscribe to every showLoading property on every service in my app.component.ts, just a single base service.

    – Viqas
    Jan 3 at 11:33














1












1








1







It's nothing to do with singleton, but suggestions about different instance is correct, I will try to explain step by step.



this two instances (BaseServiceService, FileServiceService) which you injected in app.component.ts constructor are different and are initialized independently, that's why this.fileService.callBase(); wont interact/trigger this.baseService.showLoading BehaviourSubject, if you change this.baseService.showLoading.subscribe(x => console.log('new val: ' + x)); this line with this.fileService.showLoading.subscribe(x => console.log('new val: ' + x)); it will work as you expected, now you can just remove private baseService: BaseServiceService injection from constructor and BaseServiceService from providers: [FileServiceService, BaseServiceService]



----Edited----



I think i get what you intend to do, so I modified your demo. here is link https://stackblitz.com/edit/angular-r2wv24






share|improve this answer















It's nothing to do with singleton, but suggestions about different instance is correct, I will try to explain step by step.



this two instances (BaseServiceService, FileServiceService) which you injected in app.component.ts constructor are different and are initialized independently, that's why this.fileService.callBase(); wont interact/trigger this.baseService.showLoading BehaviourSubject, if you change this.baseService.showLoading.subscribe(x => console.log('new val: ' + x)); this line with this.fileService.showLoading.subscribe(x => console.log('new val: ' + x)); it will work as you expected, now you can just remove private baseService: BaseServiceService injection from constructor and BaseServiceService from providers: [FileServiceService, BaseServiceService]



----Edited----



I think i get what you intend to do, so I modified your demo. here is link https://stackblitz.com/edit/angular-r2wv24







share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 3 at 11:54

























answered Jan 3 at 10:34









Ako JavakhishviliAko Javakhishvili

436




436













  • Good explanation, I understand, but I want to use the base service as this is what every other service will be using. I don't want to subscribe to every showLoading property on every service in my app.component.ts, just a single base service.

    – Viqas
    Jan 3 at 11:33



















  • Good explanation, I understand, but I want to use the base service as this is what every other service will be using. I don't want to subscribe to every showLoading property on every service in my app.component.ts, just a single base service.

    – Viqas
    Jan 3 at 11:33

















Good explanation, I understand, but I want to use the base service as this is what every other service will be using. I don't want to subscribe to every showLoading property on every service in my app.component.ts, just a single base service.

– Viqas
Jan 3 at 11:33





Good explanation, I understand, but I want to use the base service as this is what every other service will be using. I don't want to subscribe to every showLoading property on every service in my app.component.ts, just a single base service.

– Viqas
Jan 3 at 11:33













0














Your FileService class extends the BaseService class, which means both classes will have a property showLoading.



Only your FileService service is called through the callBase() method, which means only the showLoading property from your FileService will be notified of any change.



I changed this line in your app.component.ts to subscribe to the FileService instead of the BaseService and it works as intended.



this.fileService.showLoading.subscribe(x => console.log('new val app: ' + x));


I assume you wanted a kind of abstract service to define your showLoading at a higher level ?






share|improve this answer
























  • Yes I do want an abstract service at a higher level. How can I achieve this with my current scenario?

    – Viqas
    Jan 3 at 11:29











  • I guess not extending BaseService would be the first step, and then having your FileService subscribe to your BaseService inner observable ? There are multiple ways to do what you want, but without the big picture in mind it is quite hard to propose a solution based on a mock example...

    – Alex Beugnet
    Jan 3 at 12:14
















0














Your FileService class extends the BaseService class, which means both classes will have a property showLoading.



Only your FileService service is called through the callBase() method, which means only the showLoading property from your FileService will be notified of any change.



I changed this line in your app.component.ts to subscribe to the FileService instead of the BaseService and it works as intended.



this.fileService.showLoading.subscribe(x => console.log('new val app: ' + x));


I assume you wanted a kind of abstract service to define your showLoading at a higher level ?






share|improve this answer
























  • Yes I do want an abstract service at a higher level. How can I achieve this with my current scenario?

    – Viqas
    Jan 3 at 11:29











  • I guess not extending BaseService would be the first step, and then having your FileService subscribe to your BaseService inner observable ? There are multiple ways to do what you want, but without the big picture in mind it is quite hard to propose a solution based on a mock example...

    – Alex Beugnet
    Jan 3 at 12:14














0












0








0







Your FileService class extends the BaseService class, which means both classes will have a property showLoading.



Only your FileService service is called through the callBase() method, which means only the showLoading property from your FileService will be notified of any change.



I changed this line in your app.component.ts to subscribe to the FileService instead of the BaseService and it works as intended.



this.fileService.showLoading.subscribe(x => console.log('new val app: ' + x));


I assume you wanted a kind of abstract service to define your showLoading at a higher level ?






share|improve this answer













Your FileService class extends the BaseService class, which means both classes will have a property showLoading.



Only your FileService service is called through the callBase() method, which means only the showLoading property from your FileService will be notified of any change.



I changed this line in your app.component.ts to subscribe to the FileService instead of the BaseService and it works as intended.



this.fileService.showLoading.subscribe(x => console.log('new val app: ' + x));


I assume you wanted a kind of abstract service to define your showLoading at a higher level ?







share|improve this answer












share|improve this answer



share|improve this answer










answered Jan 3 at 10:30









Alex BeugnetAlex Beugnet

2,20531537




2,20531537













  • Yes I do want an abstract service at a higher level. How can I achieve this with my current scenario?

    – Viqas
    Jan 3 at 11:29











  • I guess not extending BaseService would be the first step, and then having your FileService subscribe to your BaseService inner observable ? There are multiple ways to do what you want, but without the big picture in mind it is quite hard to propose a solution based on a mock example...

    – Alex Beugnet
    Jan 3 at 12:14



















  • Yes I do want an abstract service at a higher level. How can I achieve this with my current scenario?

    – Viqas
    Jan 3 at 11:29











  • I guess not extending BaseService would be the first step, and then having your FileService subscribe to your BaseService inner observable ? There are multiple ways to do what you want, but without the big picture in mind it is quite hard to propose a solution based on a mock example...

    – Alex Beugnet
    Jan 3 at 12:14

















Yes I do want an abstract service at a higher level. How can I achieve this with my current scenario?

– Viqas
Jan 3 at 11:29





Yes I do want an abstract service at a higher level. How can I achieve this with my current scenario?

– Viqas
Jan 3 at 11:29













I guess not extending BaseService would be the first step, and then having your FileService subscribe to your BaseService inner observable ? There are multiple ways to do what you want, but without the big picture in mind it is quite hard to propose a solution based on a mock example...

– Alex Beugnet
Jan 3 at 12:14





I guess not extending BaseService would be the first step, and then having your FileService subscribe to your BaseService inner observable ? There are multiple ways to do what you want, but without the big picture in mind it is quite hard to propose a solution based on a mock example...

– Alex Beugnet
Jan 3 at 12:14


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54020211%2frxjs-subscribe-not-working-when-subscribing-to-behavior-subject-in-base-class%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

MongoDB - Not Authorized To Execute Command

in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith

Npm cannot find a required file even through it is in the searched directory