Angular rxjs mix observable and promises





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







2















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();
}









share|improve this question

























  • 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 an Observable<T>

    – Alexander Staroselsky
    Jan 4 at 14:55


















2















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();
}









share|improve this question

























  • 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 an Observable<T>

    – Alexander Staroselsky
    Jan 4 at 14:55














2












2








2








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();
}









share|improve this question
















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();
}






angular promise rxjs subscription






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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



















  • 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 an Observable<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












1 Answer
1






active

oldest

votes


















0














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
);
}
}





share|improve this answer
























  • Many thanks ! I sorted out the problem the share() method and a subscriber

    – Canopy
    Jan 4 at 16:03












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%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









0














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
);
}
}





share|improve this answer
























  • Many thanks ! I sorted out the problem the share() method and a subscriber

    – Canopy
    Jan 4 at 16:03
















0














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
);
}
}





share|improve this answer
























  • Many thanks ! I sorted out the problem the share() method and a subscriber

    – Canopy
    Jan 4 at 16:03














0












0








0







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
);
}
}





share|improve this answer













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
);
}
}






share|improve this answer












share|improve this answer



share|improve this answer










answered Jan 4 at 14:56









Pierre R-APierre R-A

346713




346713













  • 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

















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




















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%2f54040900%2fangular-rxjs-mix-observable-and-promises%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

Angular Downloading a file using contenturl with Basic Authentication

Olmecas

Can't read property showImagePicker of undefined in react native iOS