Angular rxjs mix observable and promises

Multi tool use
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I'm developing an Angular app and I use Rxjs, Observables and all the stuff to transfer data from my Data Access Layer to components.
I have a Service which gets Bootstrapping data (named B).
Another service (named A) fetches these data and gives them to a component through a Subject.
My goal is to keep these data in my service A but only when I get the data the first time. So, I will use a Promise.
I need my Promise to "subscribe" to the Subject and then "unsubscribe" directly.
I tried the a BehaviorSubject, A ReplaySubject but the Promise never gets called...
The Bootstrap Service
export class BService {
propsFetched: Subject<BootstrapProperties> = new Subject<BootstrapProperties>();
constructor(private httpClient: HttpClient) { //... }
init() {
this.fetchBootstrapProperties().then(
(res) => {
// ...
this.propsFetched.next({ ...res });
}
);
}
private fetchBootstrapProperties(): Promise<BootstrapProperties> {
const url = UrlResolver.resolveUrl(UrlResolver.EndPoint.BOOTSTRAP);
return this.httpClient.get<BootstrapProperties>(url).toPromise();
}
getDefaultData(): Observable<Data> {
return this.propsFetched.pipe(map(data => {
// Some data computation
return data;
}));
}
}
The service which gets data and transfers them to components
export class AService {
sub$ = new BehaviorSubject<Data>();
constructor(private bService: BService) {
// This one works, it's used by my component.
this.sub$ = this.bService.getDefaultData() as BehaviorSubject<Data>;
// Now, I want to "keep a copy" of these data, ... But my promise never fires.
this.sub$.toPromise().then(d => console.log(d));
}
Module and Bootstrapping config
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule,
// ...
],
providers: [
{
provide: APP_INITIALIZER,
useFactory: init,
deps: [BService],
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
export function init(bService: BService) {
return () => bService.init();
}

add a comment |
I'm developing an Angular app and I use Rxjs, Observables and all the stuff to transfer data from my Data Access Layer to components.
I have a Service which gets Bootstrapping data (named B).
Another service (named A) fetches these data and gives them to a component through a Subject.
My goal is to keep these data in my service A but only when I get the data the first time. So, I will use a Promise.
I need my Promise to "subscribe" to the Subject and then "unsubscribe" directly.
I tried the a BehaviorSubject, A ReplaySubject but the Promise never gets called...
The Bootstrap Service
export class BService {
propsFetched: Subject<BootstrapProperties> = new Subject<BootstrapProperties>();
constructor(private httpClient: HttpClient) { //... }
init() {
this.fetchBootstrapProperties().then(
(res) => {
// ...
this.propsFetched.next({ ...res });
}
);
}
private fetchBootstrapProperties(): Promise<BootstrapProperties> {
const url = UrlResolver.resolveUrl(UrlResolver.EndPoint.BOOTSTRAP);
return this.httpClient.get<BootstrapProperties>(url).toPromise();
}
getDefaultData(): Observable<Data> {
return this.propsFetched.pipe(map(data => {
// Some data computation
return data;
}));
}
}
The service which gets data and transfers them to components
export class AService {
sub$ = new BehaviorSubject<Data>();
constructor(private bService: BService) {
// This one works, it's used by my component.
this.sub$ = this.bService.getDefaultData() as BehaviorSubject<Data>;
// Now, I want to "keep a copy" of these data, ... But my promise never fires.
this.sub$.toPromise().then(d => console.log(d));
}
Module and Bootstrapping config
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule,
// ...
],
providers: [
{
provide: APP_INITIALIZER,
useFactory: init,
deps: [BService],
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
export function init(bService: BService) {
return () => bService.init();
}

Why does fetchBootstrapProperties returns a Promise? Can't you just return an Observable? Also, with your snippet, you never call init() and the promise is never called.
– Pierre R-A
Jan 4 at 14:35
fetchBootstrapProperties will be called once, I call theinit()
method at the application bootstrap
– Canopy
Jan 4 at 14:39
You can use an operator such as from to turn aPromise<T>
into anObservable<T>
– Alexander Staroselsky
Jan 4 at 14:55
add a comment |
I'm developing an Angular app and I use Rxjs, Observables and all the stuff to transfer data from my Data Access Layer to components.
I have a Service which gets Bootstrapping data (named B).
Another service (named A) fetches these data and gives them to a component through a Subject.
My goal is to keep these data in my service A but only when I get the data the first time. So, I will use a Promise.
I need my Promise to "subscribe" to the Subject and then "unsubscribe" directly.
I tried the a BehaviorSubject, A ReplaySubject but the Promise never gets called...
The Bootstrap Service
export class BService {
propsFetched: Subject<BootstrapProperties> = new Subject<BootstrapProperties>();
constructor(private httpClient: HttpClient) { //... }
init() {
this.fetchBootstrapProperties().then(
(res) => {
// ...
this.propsFetched.next({ ...res });
}
);
}
private fetchBootstrapProperties(): Promise<BootstrapProperties> {
const url = UrlResolver.resolveUrl(UrlResolver.EndPoint.BOOTSTRAP);
return this.httpClient.get<BootstrapProperties>(url).toPromise();
}
getDefaultData(): Observable<Data> {
return this.propsFetched.pipe(map(data => {
// Some data computation
return data;
}));
}
}
The service which gets data and transfers them to components
export class AService {
sub$ = new BehaviorSubject<Data>();
constructor(private bService: BService) {
// This one works, it's used by my component.
this.sub$ = this.bService.getDefaultData() as BehaviorSubject<Data>;
// Now, I want to "keep a copy" of these data, ... But my promise never fires.
this.sub$.toPromise().then(d => console.log(d));
}
Module and Bootstrapping config
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule,
// ...
],
providers: [
{
provide: APP_INITIALIZER,
useFactory: init,
deps: [BService],
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
export function init(bService: BService) {
return () => bService.init();
}

I'm developing an Angular app and I use Rxjs, Observables and all the stuff to transfer data from my Data Access Layer to components.
I have a Service which gets Bootstrapping data (named B).
Another service (named A) fetches these data and gives them to a component through a Subject.
My goal is to keep these data in my service A but only when I get the data the first time. So, I will use a Promise.
I need my Promise to "subscribe" to the Subject and then "unsubscribe" directly.
I tried the a BehaviorSubject, A ReplaySubject but the Promise never gets called...
The Bootstrap Service
export class BService {
propsFetched: Subject<BootstrapProperties> = new Subject<BootstrapProperties>();
constructor(private httpClient: HttpClient) { //... }
init() {
this.fetchBootstrapProperties().then(
(res) => {
// ...
this.propsFetched.next({ ...res });
}
);
}
private fetchBootstrapProperties(): Promise<BootstrapProperties> {
const url = UrlResolver.resolveUrl(UrlResolver.EndPoint.BOOTSTRAP);
return this.httpClient.get<BootstrapProperties>(url).toPromise();
}
getDefaultData(): Observable<Data> {
return this.propsFetched.pipe(map(data => {
// Some data computation
return data;
}));
}
}
The service which gets data and transfers them to components
export class AService {
sub$ = new BehaviorSubject<Data>();
constructor(private bService: BService) {
// This one works, it's used by my component.
this.sub$ = this.bService.getDefaultData() as BehaviorSubject<Data>;
// Now, I want to "keep a copy" of these data, ... But my promise never fires.
this.sub$.toPromise().then(d => console.log(d));
}
Module and Bootstrapping config
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule,
// ...
],
providers: [
{
provide: APP_INITIALIZER,
useFactory: init,
deps: [BService],
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
export function init(bService: BService) {
return () => bService.init();
}


edited Jan 4 at 14:45
Canopy
asked Jan 4 at 14:31
CanopyCanopy
215
215
Why does fetchBootstrapProperties returns a Promise? Can't you just return an Observable? Also, with your snippet, you never call init() and the promise is never called.
– Pierre R-A
Jan 4 at 14:35
fetchBootstrapProperties will be called once, I call theinit()
method at the application bootstrap
– Canopy
Jan 4 at 14:39
You can use an operator such as from to turn aPromise<T>
into anObservable<T>
– Alexander Staroselsky
Jan 4 at 14:55
add a comment |
Why does fetchBootstrapProperties returns a Promise? Can't you just return an Observable? Also, with your snippet, you never call init() and the promise is never called.
– Pierre R-A
Jan 4 at 14:35
fetchBootstrapProperties will be called once, I call theinit()
method at the application bootstrap
– Canopy
Jan 4 at 14:39
You can use an operator such as from to turn aPromise<T>
into anObservable<T>
– Alexander Staroselsky
Jan 4 at 14:55
Why does fetchBootstrapProperties returns a Promise? Can't you just return an Observable? Also, with your snippet, you never call init() and the promise is never called.
– Pierre R-A
Jan 4 at 14:35
Why does fetchBootstrapProperties returns a Promise? Can't you just return an Observable? Also, with your snippet, you never call init() and the promise is never called.
– Pierre R-A
Jan 4 at 14:35
fetchBootstrapProperties will be called once, I call the
init()
method at the application bootstrap– Canopy
Jan 4 at 14:39
fetchBootstrapProperties will be called once, I call the
init()
method at the application bootstrap– Canopy
Jan 4 at 14:39
You can use an operator such as from to turn a
Promise<T>
into an Observable<T>
– Alexander Staroselsky
Jan 4 at 14:55
You can use an operator such as from to turn a
Promise<T>
into an Observable<T>
– Alexander Staroselsky
Jan 4 at 14:55
add a comment |
1 Answer
1
active
oldest
votes
I would suggest keeping using Observables. There is the pipe operator share that share the result of the observable to everyone subscribing to this Observable. The call is made only once.
export class BService {
public fetchBootstrapProperties$: Observable<BootstrapProperties>;
constructor() {
this.fetchBootstrapProperties$ = this.httpClient.get<BootstrapProperties>(url).pipe(
map(data => {
// computation
// return data
}),
share()
);
}
}
export class AService {
constructor(bService: BService) {
this.bService.fetchBootstrapProperties$.subscribe(data => {
// get your data
);
}
}
Many thanks ! I sorted out the problem theshare()
method and a subscriber
– Canopy
Jan 4 at 16:03
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54040900%2fangular-rxjs-mix-observable-and-promises%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I would suggest keeping using Observables. There is the pipe operator share that share the result of the observable to everyone subscribing to this Observable. The call is made only once.
export class BService {
public fetchBootstrapProperties$: Observable<BootstrapProperties>;
constructor() {
this.fetchBootstrapProperties$ = this.httpClient.get<BootstrapProperties>(url).pipe(
map(data => {
// computation
// return data
}),
share()
);
}
}
export class AService {
constructor(bService: BService) {
this.bService.fetchBootstrapProperties$.subscribe(data => {
// get your data
);
}
}
Many thanks ! I sorted out the problem theshare()
method and a subscriber
– Canopy
Jan 4 at 16:03
add a comment |
I would suggest keeping using Observables. There is the pipe operator share that share the result of the observable to everyone subscribing to this Observable. The call is made only once.
export class BService {
public fetchBootstrapProperties$: Observable<BootstrapProperties>;
constructor() {
this.fetchBootstrapProperties$ = this.httpClient.get<BootstrapProperties>(url).pipe(
map(data => {
// computation
// return data
}),
share()
);
}
}
export class AService {
constructor(bService: BService) {
this.bService.fetchBootstrapProperties$.subscribe(data => {
// get your data
);
}
}
Many thanks ! I sorted out the problem theshare()
method and a subscriber
– Canopy
Jan 4 at 16:03
add a comment |
I would suggest keeping using Observables. There is the pipe operator share that share the result of the observable to everyone subscribing to this Observable. The call is made only once.
export class BService {
public fetchBootstrapProperties$: Observable<BootstrapProperties>;
constructor() {
this.fetchBootstrapProperties$ = this.httpClient.get<BootstrapProperties>(url).pipe(
map(data => {
// computation
// return data
}),
share()
);
}
}
export class AService {
constructor(bService: BService) {
this.bService.fetchBootstrapProperties$.subscribe(data => {
// get your data
);
}
}
I would suggest keeping using Observables. There is the pipe operator share that share the result of the observable to everyone subscribing to this Observable. The call is made only once.
export class BService {
public fetchBootstrapProperties$: Observable<BootstrapProperties>;
constructor() {
this.fetchBootstrapProperties$ = this.httpClient.get<BootstrapProperties>(url).pipe(
map(data => {
// computation
// return data
}),
share()
);
}
}
export class AService {
constructor(bService: BService) {
this.bService.fetchBootstrapProperties$.subscribe(data => {
// get your data
);
}
}
answered Jan 4 at 14:56


Pierre R-APierre R-A
346713
346713
Many thanks ! I sorted out the problem theshare()
method and a subscriber
– Canopy
Jan 4 at 16:03
add a comment |
Many thanks ! I sorted out the problem theshare()
method and a subscriber
– Canopy
Jan 4 at 16:03
Many thanks ! I sorted out the problem the
share()
method and a subscriber– Canopy
Jan 4 at 16:03
Many thanks ! I sorted out the problem the
share()
method and a subscriber– Canopy
Jan 4 at 16:03
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54040900%2fangular-rxjs-mix-observable-and-promises%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
k6Pts bVTTiBsVFiy c2u,b,znmFzj 9VHIFGPV
Why does fetchBootstrapProperties returns a Promise? Can't you just return an Observable? Also, with your snippet, you never call init() and the promise is never called.
– Pierre R-A
Jan 4 at 14:35
fetchBootstrapProperties will be called once, I call the
init()
method at the application bootstrap– Canopy
Jan 4 at 14:39
You can use an operator such as from to turn a
Promise<T>
into anObservable<T>
– Alexander Staroselsky
Jan 4 at 14:55