Initial call for Angular2 service returns null

Dealing with a parent component that has children routes, my goal is to share a project variable among them. The project value may change, and I need all route pages to reflect this change. Following the guide in the Angular 2 tutorial on achieving this, I encountered an issue when initializing my observable. Upon the first call, the value fails to display initially but shows up upon updates. The reason behind why the project variable lacks an initial value remains elusive. Any insights on this behavior and possible fixes are greatly appreciated.

Parent Route: (Where project can be set and updated)

onSubmit(value: any, valid: any) {
    if (valid) {
        // HTTP request to retrieve project 
        this.ad.searchProject(value)
            .subscribe(
            response => {
                // If project found, set its value in the service
                this.ad.setProject(response);
                // Navigate to child route
                this.router.navigate(['./project'], { relativeTo: this.route });
            },
            error => {
                console.log(error)
            },
            () => {
                console.log("Project Loaded");
            }
            );
    }
}

Project service.ts

@Injectable()
export class ProjectService {
    public project: Project;
    // Observable string sources
    private projectSource = new Subject<Project>();
    // Observable string streams
    projectListener$ = this.projectSource.asObservable();
    constructor(private http: Http) {
    }
    searchProject(value: string): Observable<any> {
        return this.http.post('/controller/Project/SearchProject', { value: value }, { headers: headers })
            .map(response => response.json());
    }
    // Service message commands
    setProject(project: Project) {
        this.projectSource.next(project);
        console.log("call setProject"); 
    }
}

Child Route:

export class ChildComponent {
    project: Project = null;
    subscription: Subscription;
    constructor(private ad: ProjectService) {
        console.log("call child route"); 
        this.subscription = this.ad.projectListener$.subscribe(
            value => {
                // Triggered after the second value entry
                console.log("call subscription");
                console.log(value);
                this.project = value;
            });
    }
}

Console Log

[HMR] connected
call parent route
Gravity_Project
setProject
Project Loaded
call child route
// Completed first project entry
Waves Project
call subscription
Object {id: 1001, typeID: 45004, studentID: 10000…}
call setProject
Project Loaded
// Completed second project entry

Answer №1

The correct answer is the Behavior Subject ()

"A Behavior Subject is a special type of subject in Angular, allowing for subscription to messages like any other observable. The key characteristics of a behavior subject include:

1. Requiring an initial value to always return a value upon subscription, even if no new values have been received. 2. Providing the last value of the subject upon subscription, rather than waiting for the next event as with a regular observable. 3. Allowing retrieval of the last value through non-observable code using the getValue() method."

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Angular 2 Guide on macOS Sierra Shows "Page Not Found" Error in Web Browser

I've been delving into Angular 2 with TypeScript on my OS X machine. Following the tutorial to the T, I didn't encounter any errors during compilation. Upon executing the npm start command, everything seemed to be smooth sailing as a new tab open ...

Encountering an error in Angular 4: 'Cannot find property on specified component type'

I recently embarked on the journey of learning Angular 4 and TypeScript, but I've encountered my first obstacle. My current challenge involves creating a simple date and time component. Despite having a seemingly correct Javascript code, I believe I ...

Encountering a Npm ERR! when deploying Angular 6 to Heroku due to missing Start script

I am experiencing an issue with my simple angular 6 app after deploying it to Heroku. When I check the logs using the command heroku logs, I encounter the following error: 2018-07-15T00:45:51.000000+00:00 app[api]: Build succeeded 2018-07-15T00:45:53.9012 ...

Using Express to serve both the Angular application and its API

Currently, I have set up an Express app with the following routing configuration: app.use(express.static(path.join(__dirname, '../angular-app/dist'))); app.use('/', express.Router().get('/', function(req, res, next) { ...

Utilizing Angular signals to facilitate data sharing among child components

I have a main component X with two sub-components Y and Z. I am experimenting with signals in Angular 17. My query is how can I pass the value of a signal from sub-component Y to sub-component Z? I have attempted the following approach which works initial ...

What enables typescript to be eligible for transpiling is its equivalent level of abstraction to javascript?

Transpilation is the act of converting code from one language to another with a similar level of abstraction. Can you point out some distinctive characteristics that indicate TypeScript transpires into JavaScript? ...

What is the best way to write unit test cases for an eventEmitter object that is present within an abstract class in Jasmine/Angular8?

I'm attempting to write unit test cases for the given scenario, but encountering some issues. AbstractClass.ts @Directive export abstract class AbstractComponent<search = string> { @Output() public search: EventEmitter<string> = new E ...

What sets apart the concepts of Boolean and boolean when it comes to Typescript?

I would like to understand the distinction between Boolean and boolean in Typescript. Can anyone provide an explanation? ...

Tips for passing the same value to two components using vuejs $emit

Can someone help with typing in Main, where the value can also be Test World? You can view a sample here >>> Sample The issue I'm facing is that when a user adds an item to the cart, the cart shows one more than it should. I've tried t ...

The graph that should appear in Angular2 with ng2-charts is missing

I'm currently working on a project that requires implementing charts using Angular2 (version 2.4.8). I am utilizing ng2-charts (version 1.5.0) and the corresponding version of chart.js is 2.5.0. Initially, I started by copying an example code from the ...

TS1057: It is required that an async function or method has a return type that can be awaited

There was a recent Github issue reported on March 28th regarding async arrow functions generating faulty code when targeting ES5, resulting in the error message: TS1057: An async function or method must have a valid awaitable return type You can find t ...

Inheriting Components from Templates

Insight on Motivation There are countless situations where we may require multiple components to share the same functionalities. It is not ideal (and definitely shouldn't be done!) to simply copy child components. This is where the concept of inherit ...

Upgrading from Angular 5 to Angular 7: A seamless migration journey

Following my migration from Angular 5 to Angular 7, I encountered an issue with RxJs operations such as observables and @ngrx/store. Here is the error message I received: ERROR in node_modules/@ngrx/store/src/actions_subject.d.ts(2,10): error TS2305: Mo ...

Is there a way for me to steer clear of using optional chaining in Typescript?

I'm currently working on storing object data known as Targetfarms in redux. I've defined a type named Farmstype for the Targetfarms. However, when I retrieve the Targetfarms using useSelector in the MainPage component and try to access targetfar ...

What is the process for passing information to a nested component structure with parent-child-child relationships?

I am facing an issue with three nested components (C1, C2, C3) where C2 is called within C1 and C3 is called within C2. My goal is to pass data from C1 to C3 using property binding. In the template of C1, I successfully bound a variable that I can access ...

Securing redirection in WebPart using Azure AD: Best practices

I've successfully created a Sharepoint Webpart with a straightforward goal: authenticate users on an external website embedded within Sharepoint. This external site utilizes Azure AD for user logins. However, my current implementation has a significa ...

What could be causing TypeORM to create an additional column in the query

Why does this TypeORM query produce the following result? const result6 = await getConnection() .createQueryBuilder() .select('actor.name') .from(Actor,'actor') .innerJoin('actor.castings',&apos ...

The pathway specified is untraceable by the gulp system

Hey there, I've encountered an issue with my project that uses gulp. The gulpfile.js suddenly stopped working without any changes made to it. The output I'm getting is: cmd.exe /c gulp --tasks-simple The system cannot find the path specified. ...

Is it possible for a lambda in TypeScript to have access to the class scope but return undefined

In my TypeScript code, I have a class used as a Pipe in Angular 2 to render markdown. It compiles successfully but encounters a runtime exception on a specific line: var Remarkable = require('remarkable'); @Pipe({ name: 'markdown' ...

Ways to reveal heavily nested components when the Angular change detector fails to detect them

A particular component called Grid has been implemented with the following template: <div *ngFor="let row of item.rows"> <div *ngFor="let col of row.cols"> <div *ngFor="let grid of col.items"> < ...