Get result from HttpGet Request in “getter” method Angular 7 service
up vote
0
down vote
favorite
This is probably pretty simple, but Angular isn't exactly my forte and it's taking me a bit more time than I anticipated. I have a service that calls an external API, and I want to get the variable on app initialisation and to use it in multiple other components.
I have the following service:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class DatabaseConnectionService {
API_URL: string = "http://localhost:4044";
apiResult;
constructor(private http: HttpClient) {
this.dbConn.getApiRoot()
.subscribe(
data => this.apiResult = { message: data['message'] }
);
}
getApiRoot() {
return this.http.get<Apiroot>(this.API_URL);
}
returnApiResult() {
return this.apiResult;
}
}
In any of the other components, I need to be able to call the returnApiResult()
and get the value of the variable, but it returns as empty since it's an observable (which I think should have already be assigned, since it's in the constructor for the service). Any help is appreciated.
angular angular7
add a comment |
up vote
0
down vote
favorite
This is probably pretty simple, but Angular isn't exactly my forte and it's taking me a bit more time than I anticipated. I have a service that calls an external API, and I want to get the variable on app initialisation and to use it in multiple other components.
I have the following service:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class DatabaseConnectionService {
API_URL: string = "http://localhost:4044";
apiResult;
constructor(private http: HttpClient) {
this.dbConn.getApiRoot()
.subscribe(
data => this.apiResult = { message: data['message'] }
);
}
getApiRoot() {
return this.http.get<Apiroot>(this.API_URL);
}
returnApiResult() {
return this.apiResult;
}
}
In any of the other components, I need to be able to call the returnApiResult()
and get the value of the variable, but it returns as empty since it's an observable (which I think should have already be assigned, since it's in the constructor for the service). Any help is appreciated.
angular angular7
Its not necessary that you will get the response data since you initiated the call in constructor.
– Sunil Singh
Nov 9 at 15:16
Even though it's in the constructor, it's asynchronous, so there is no guarantee is has finished loading when you callreturnApiResult
. Instead, you should return the actual Observable, and callsubscribe
in the components that need it
– user184994
Nov 9 at 15:17
@user184994 Yeah, it works that way, I was kind of hoping to initialise all the data on application load, and just access it through the components. This way it would minimise the API requests too.
– Neekoy
Nov 9 at 15:19
What version of rxjs are you using?
– user184994
Nov 9 at 15:28
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
This is probably pretty simple, but Angular isn't exactly my forte and it's taking me a bit more time than I anticipated. I have a service that calls an external API, and I want to get the variable on app initialisation and to use it in multiple other components.
I have the following service:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class DatabaseConnectionService {
API_URL: string = "http://localhost:4044";
apiResult;
constructor(private http: HttpClient) {
this.dbConn.getApiRoot()
.subscribe(
data => this.apiResult = { message: data['message'] }
);
}
getApiRoot() {
return this.http.get<Apiroot>(this.API_URL);
}
returnApiResult() {
return this.apiResult;
}
}
In any of the other components, I need to be able to call the returnApiResult()
and get the value of the variable, but it returns as empty since it's an observable (which I think should have already be assigned, since it's in the constructor for the service). Any help is appreciated.
angular angular7
This is probably pretty simple, but Angular isn't exactly my forte and it's taking me a bit more time than I anticipated. I have a service that calls an external API, and I want to get the variable on app initialisation and to use it in multiple other components.
I have the following service:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class DatabaseConnectionService {
API_URL: string = "http://localhost:4044";
apiResult;
constructor(private http: HttpClient) {
this.dbConn.getApiRoot()
.subscribe(
data => this.apiResult = { message: data['message'] }
);
}
getApiRoot() {
return this.http.get<Apiroot>(this.API_URL);
}
returnApiResult() {
return this.apiResult;
}
}
In any of the other components, I need to be able to call the returnApiResult()
and get the value of the variable, but it returns as empty since it's an observable (which I think should have already be assigned, since it's in the constructor for the service). Any help is appreciated.
angular angular7
angular angular7
edited Nov 12 at 12:31
Goncalo Peres
9571311
9571311
asked Nov 9 at 15:14
Neekoy
798921
798921
Its not necessary that you will get the response data since you initiated the call in constructor.
– Sunil Singh
Nov 9 at 15:16
Even though it's in the constructor, it's asynchronous, so there is no guarantee is has finished loading when you callreturnApiResult
. Instead, you should return the actual Observable, and callsubscribe
in the components that need it
– user184994
Nov 9 at 15:17
@user184994 Yeah, it works that way, I was kind of hoping to initialise all the data on application load, and just access it through the components. This way it would minimise the API requests too.
– Neekoy
Nov 9 at 15:19
What version of rxjs are you using?
– user184994
Nov 9 at 15:28
add a comment |
Its not necessary that you will get the response data since you initiated the call in constructor.
– Sunil Singh
Nov 9 at 15:16
Even though it's in the constructor, it's asynchronous, so there is no guarantee is has finished loading when you callreturnApiResult
. Instead, you should return the actual Observable, and callsubscribe
in the components that need it
– user184994
Nov 9 at 15:17
@user184994 Yeah, it works that way, I was kind of hoping to initialise all the data on application load, and just access it through the components. This way it would minimise the API requests too.
– Neekoy
Nov 9 at 15:19
What version of rxjs are you using?
– user184994
Nov 9 at 15:28
Its not necessary that you will get the response data since you initiated the call in constructor.
– Sunil Singh
Nov 9 at 15:16
Its not necessary that you will get the response data since you initiated the call in constructor.
– Sunil Singh
Nov 9 at 15:16
Even though it's in the constructor, it's asynchronous, so there is no guarantee is has finished loading when you call
returnApiResult
. Instead, you should return the actual Observable, and call subscribe
in the components that need it– user184994
Nov 9 at 15:17
Even though it's in the constructor, it's asynchronous, so there is no guarantee is has finished loading when you call
returnApiResult
. Instead, you should return the actual Observable, and call subscribe
in the components that need it– user184994
Nov 9 at 15:17
@user184994 Yeah, it works that way, I was kind of hoping to initialise all the data on application load, and just access it through the components. This way it would minimise the API requests too.
– Neekoy
Nov 9 at 15:19
@user184994 Yeah, it works that way, I was kind of hoping to initialise all the data on application load, and just access it through the components. This way it would minimise the API requests too.
– Neekoy
Nov 9 at 15:19
What version of rxjs are you using?
– user184994
Nov 9 at 15:28
What version of rxjs are you using?
– user184994
Nov 9 at 15:28
add a comment |
1 Answer
1
active
oldest
votes
up vote
1
down vote
accepted
In your constructor, change the code like so:
import { shareReplay } from 'rxjs/operators';
//...
constructor(private http: HttpClient) {
this.apiResult = this.dbConn.getApiRot().pipe(shareReplay());
}
By using the shareReplay
operator, it will share the results among multiple subscribers, and replay the results. This way, your components can still subscribe:
this.service.apiResult.subscribe(() => console.log("Done"))
But the data will only need to be loaded by the service once, on application load
Perfect - it does the trick and leaves only 1 line of logic in the other components which is what I was going for. I think it's worth mentioning that last() is contained in "import { last } from 'rxjs/operators';", other than that this is the correct answer. Thanks :)
– Neekoy
Nov 9 at 15:44
@Neekoy Very good point, I'll add it in now. Glad to help
– user184994
Nov 9 at 15:44
Not sure this will only load the data once if more than one component subscribes to it.
– Aviad P.
Nov 9 at 16:29
@AviadP Having just played around with this, you're completely right, my mistake. @Neekoy I have made a change to useshareReplay
instead oflast
, which should be more efficient. Please use that instead
– user184994
Nov 9 at 18:15
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
In your constructor, change the code like so:
import { shareReplay } from 'rxjs/operators';
//...
constructor(private http: HttpClient) {
this.apiResult = this.dbConn.getApiRot().pipe(shareReplay());
}
By using the shareReplay
operator, it will share the results among multiple subscribers, and replay the results. This way, your components can still subscribe:
this.service.apiResult.subscribe(() => console.log("Done"))
But the data will only need to be loaded by the service once, on application load
Perfect - it does the trick and leaves only 1 line of logic in the other components which is what I was going for. I think it's worth mentioning that last() is contained in "import { last } from 'rxjs/operators';", other than that this is the correct answer. Thanks :)
– Neekoy
Nov 9 at 15:44
@Neekoy Very good point, I'll add it in now. Glad to help
– user184994
Nov 9 at 15:44
Not sure this will only load the data once if more than one component subscribes to it.
– Aviad P.
Nov 9 at 16:29
@AviadP Having just played around with this, you're completely right, my mistake. @Neekoy I have made a change to useshareReplay
instead oflast
, which should be more efficient. Please use that instead
– user184994
Nov 9 at 18:15
add a comment |
up vote
1
down vote
accepted
In your constructor, change the code like so:
import { shareReplay } from 'rxjs/operators';
//...
constructor(private http: HttpClient) {
this.apiResult = this.dbConn.getApiRot().pipe(shareReplay());
}
By using the shareReplay
operator, it will share the results among multiple subscribers, and replay the results. This way, your components can still subscribe:
this.service.apiResult.subscribe(() => console.log("Done"))
But the data will only need to be loaded by the service once, on application load
Perfect - it does the trick and leaves only 1 line of logic in the other components which is what I was going for. I think it's worth mentioning that last() is contained in "import { last } from 'rxjs/operators';", other than that this is the correct answer. Thanks :)
– Neekoy
Nov 9 at 15:44
@Neekoy Very good point, I'll add it in now. Glad to help
– user184994
Nov 9 at 15:44
Not sure this will only load the data once if more than one component subscribes to it.
– Aviad P.
Nov 9 at 16:29
@AviadP Having just played around with this, you're completely right, my mistake. @Neekoy I have made a change to useshareReplay
instead oflast
, which should be more efficient. Please use that instead
– user184994
Nov 9 at 18:15
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
In your constructor, change the code like so:
import { shareReplay } from 'rxjs/operators';
//...
constructor(private http: HttpClient) {
this.apiResult = this.dbConn.getApiRot().pipe(shareReplay());
}
By using the shareReplay
operator, it will share the results among multiple subscribers, and replay the results. This way, your components can still subscribe:
this.service.apiResult.subscribe(() => console.log("Done"))
But the data will only need to be loaded by the service once, on application load
In your constructor, change the code like so:
import { shareReplay } from 'rxjs/operators';
//...
constructor(private http: HttpClient) {
this.apiResult = this.dbConn.getApiRot().pipe(shareReplay());
}
By using the shareReplay
operator, it will share the results among multiple subscribers, and replay the results. This way, your components can still subscribe:
this.service.apiResult.subscribe(() => console.log("Done"))
But the data will only need to be loaded by the service once, on application load
edited Nov 9 at 18:14
answered Nov 9 at 15:30
user184994
10.7k11526
10.7k11526
Perfect - it does the trick and leaves only 1 line of logic in the other components which is what I was going for. I think it's worth mentioning that last() is contained in "import { last } from 'rxjs/operators';", other than that this is the correct answer. Thanks :)
– Neekoy
Nov 9 at 15:44
@Neekoy Very good point, I'll add it in now. Glad to help
– user184994
Nov 9 at 15:44
Not sure this will only load the data once if more than one component subscribes to it.
– Aviad P.
Nov 9 at 16:29
@AviadP Having just played around with this, you're completely right, my mistake. @Neekoy I have made a change to useshareReplay
instead oflast
, which should be more efficient. Please use that instead
– user184994
Nov 9 at 18:15
add a comment |
Perfect - it does the trick and leaves only 1 line of logic in the other components which is what I was going for. I think it's worth mentioning that last() is contained in "import { last } from 'rxjs/operators';", other than that this is the correct answer. Thanks :)
– Neekoy
Nov 9 at 15:44
@Neekoy Very good point, I'll add it in now. Glad to help
– user184994
Nov 9 at 15:44
Not sure this will only load the data once if more than one component subscribes to it.
– Aviad P.
Nov 9 at 16:29
@AviadP Having just played around with this, you're completely right, my mistake. @Neekoy I have made a change to useshareReplay
instead oflast
, which should be more efficient. Please use that instead
– user184994
Nov 9 at 18:15
Perfect - it does the trick and leaves only 1 line of logic in the other components which is what I was going for. I think it's worth mentioning that last() is contained in "import { last } from 'rxjs/operators';", other than that this is the correct answer. Thanks :)
– Neekoy
Nov 9 at 15:44
Perfect - it does the trick and leaves only 1 line of logic in the other components which is what I was going for. I think it's worth mentioning that last() is contained in "import { last } from 'rxjs/operators';", other than that this is the correct answer. Thanks :)
– Neekoy
Nov 9 at 15:44
@Neekoy Very good point, I'll add it in now. Glad to help
– user184994
Nov 9 at 15:44
@Neekoy Very good point, I'll add it in now. Glad to help
– user184994
Nov 9 at 15:44
Not sure this will only load the data once if more than one component subscribes to it.
– Aviad P.
Nov 9 at 16:29
Not sure this will only load the data once if more than one component subscribes to it.
– Aviad P.
Nov 9 at 16:29
@AviadP Having just played around with this, you're completely right, my mistake. @Neekoy I have made a change to use
shareReplay
instead of last
, which should be more efficient. Please use that instead– user184994
Nov 9 at 18:15
@AviadP Having just played around with this, you're completely right, my mistake. @Neekoy I have made a change to use
shareReplay
instead of last
, which should be more efficient. Please use that instead– user184994
Nov 9 at 18:15
add a comment |
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%2f53228403%2fget-result-from-httpget-request-in-getter-method-angular-7-service%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
Its not necessary that you will get the response data since you initiated the call in constructor.
– Sunil Singh
Nov 9 at 15:16
Even though it's in the constructor, it's asynchronous, so there is no guarantee is has finished loading when you call
returnApiResult
. Instead, you should return the actual Observable, and callsubscribe
in the components that need it– user184994
Nov 9 at 15:17
@user184994 Yeah, it works that way, I was kind of hoping to initialise all the data on application load, and just access it through the components. This way it would minimise the API requests too.
– Neekoy
Nov 9 at 15:19
What version of rxjs are you using?
– user184994
Nov 9 at 15:28