Utilizing Angular 2 Service for Efficient Data Exchange Among Components

I'm experimenting with data sharing between components using a shared service. Here is the service:

@Injectable()
export class JobService {
    public jobType=null;
    public examples=[];
}

My first component sets the jobType and examples variables of the service, but due to length constraints, I will only show a snippet of the code here:

@Component({
            selector: 'app-job',
            templateUrl: './job.component.html'
})
export class JobComponent implements OnInit {

          constructor(private jobService: JobService, private authService: AuthService, private router: Router) {
            }
    ...

}

The second component retrieves these variables:

@Component({
    selector: 'app-preview',
    template:'./preview.component.html'
})
export class PreviewComponent implements OnInit {

    jobType;
    examples;

    constructor(private jobService: JobService) {
    }  
    ngOnInit() {

        this.jobType=this.jobService.jobType;
        this.examples=this.jobService.examples;
    }

}

Both components are part of the same module, where the Service is provided:

@NgModule({
    declarations: [
        JobComponent,
        JobListComponent,
        JobDetailsComponent,
        PreviewComponent
    ],
    imports: [
        CommonModule,
        FormsModule,
        RouterModule,
        TabsModule
    ],
    providers: [JobService]
})
export class JobModule {

}

However, despite ensuring that the Service is instantiated once, I am encountering issues with variable sharing when navigating from JobComponent to PreviewComponent. Any insights on why the service variables are not being shared as expected?

Answer №1

When you open the page in a new window, the state of JobService is not maintained. One way to address this issue could be by passing the state of JobService to the preview component through URL query parameters. Another approach would be to recreate the service on the new page, for instance by navigating to

/preview?jobType=something&examples=are,comma,separated,list
. Alternatively, you could save the state in the browser (local storage, cookies, etc.) and retrieve it during page initialization.

Answer №2

If you want to preserve the state of a shared resource, utilizing BehaviorSubjects is recommended.

@Injectable()
export class JobService {
    public jobType$: BehaviorSubject<any> = new BehaviorSubject('');
    public examples$: Behavior Subject<any[]> = new BehaviorSubject([]);
    public jobTypes = null;
    public examples = [];

    setJobType(jobType) {
        this.jobTypes = jobType;
        this.jobType$.next(this.jobTypes);
    }
    //Implementation for setting examples in a similar manner
}

Subsequently, within each component:

@Component({
            selector: 'app-job',
            templateUrl: './job.component.html'
})
export class JobComponent implements OnInit {

  constructor(private jobService: JobService, private authService: AuthService, private router: Router) {}

  //Subscribe to jobType$ and/or examples$ within ngOnInit or relevant method
  
  //Call the setJobType method with changes upon UI event trigger.
}


@Component({
    selector: 'app-preview',
    template:'./preview.component.html'
})
export class PreviewComponent implements OnInit {

    jobType;
    examples;

    constructor(private jobService: JobService) {
    }  
    ngOnInit() {
        this.jobService.jobType$.subscribe(result => this.jobType = result);
        this.jobService.examples$.subscribe(result => this.examples = result);
    }
}

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

Implement feature to toggle function upon clicking radio buttons using bootstrap and angular 5

Currently, I am utilizing Angular 6 and Bootstrap 4. Within my project, there exists a Bootstrap button group: <div class="btn-group btn-group-toggle" data-toggle="buttons"> <label class="btn btn-secondary"> <input type="radio" ...

How can you prevent specific dates from being selected in an Angular Datepicker?

Is there a way to exclude Monday from the "mat-datepicker" component? I've tried implementing the following code in my class component: dateFilter = (_date: any) =>{ let day = _date.getDay(); console.log(day); return day != 1; ...

Node-express can seamlessly switch between multiple databases dynamically

After extensive searching for a solution to my problem, I have come up empty-handed. If anyone has experience in similar situations, your help would be greatly appreciated. I have developed an application server in Node Express with MySQL as the database. ...

What is the best way to construct an interface in TypeScript with a variable number of properties?

Is it possible to create an interface in typescript with a variable number of string properties, ranging from 5 to potentially 50? ...

CORS regulations are preventing access

I have set up an Express server to run my Angular app for server-side rendering purposes. Initially, everything works fine when I make a request from the application. However, an issue arises when I navigate to another page and then return to the previous ...

The function this.gridApi.refreshInfiniteCache() is failing to remove the selectedRows from the grid

While utilizing the Infinite Row Model, I encountered an issue where deleting a selected row from the Grid and then refreshing the cache resulted in unexpected behavior. For example, if I delete a row with id = 1 and then call refreshInfiniteCache(), a n ...

What could be the reason for the malfunctioning of the basic angular routing animation

I implemented a basic routing Angular animation, but I'm encountering issues where it's not functioning as expected. The animation definition is located in app.component.ts with <router-outlet></router-outlet> and two links that shoul ...

What is the process of using observables in Angular to retrieve a number or variable?

While working on an angular service that calls an API and processes a large amount of data, I encountered an issue. I was trying to count the occurrences of each type in the data and send back that count along with the data itself. However, I found that wh ...

Can someone guide me on capturing an API response error using observables?

Currently working with Angular 4, my API call is functioning properly, returning the expected JSON for successful responses. However, in case of an error response, instead of receiving a JSON response as expected, I end up with a 404 HTML page (which is no ...

What method does TypeScript use to locate a .d.ts file if it is not specified in the configuration?

Recently, I encountered an issue with my TypeScript file when importing an mdx file. import mdx from "./Layout.mdx"; After some research, I found a helpful resource that suggested a solution: If you’re getting errors from TypeScript related ...

Issue with setting value using setState in TypeScript - what's the problem?

Every time I attempt to update the value of currentRole, it appears highlighted in red. Here is a screenshot for reference: const Container: React.FC<ContainerProps> = ({ children }) => { const [role, setRole] = useState<string>(); useE ...

Discovering ways to fetch an array of objects using object and arrays in JavaScript

When comparing an array of objects with a single object and listing the arrays in JavaScript, specific conditions need to be met to retrieve the array of objects: If the itemvalue and idvalue are the same, check if the arrobj cid has the same codevalue ...

What is the method to extract a single user instead of a group of users?

I am attempting to transition from a list of users to displaying the profile of a single user on a separate page. My goal is to achieve this using routerLink and passing the specific user's id to the next page. Although the routing is functioning co ...

What is the process for integrating ng-bootstrap into an Angular 5 project?

Has anyone encountered issues loading ng-bootstrap in their Angular project? I'm experiencing difficulties and would appreciate any insights. Thank you for your help! This is my app.module.ts file: import { BrowserModule } from '@angular/platf ...

Verifying the Presence of an Image in the Public Directory of Next JS

My TypeScript Next.js project contains a large number of images in the public folder. I am wondering if there is a way to verify the existence of an image before utilizing the <Image /> component from next/image. I have managed to achieve this using ...

Having trouble linking tables to Node.js with TypeScriptyntax?

I am facing an issue with mapping multiple entities using sequelize. I keep encountering the error message " Error: Profesor.hasOne called with something that's not a subclass of Sequelize.Model". How can I resolve this issue? Below is the code for t ...

The Angular NgForm method form.resetForm does not seem to be resetting properly when dealing with arrays

I encountered an issue with my simple ngForm that was previously functioning well with string input and single select dropdowns. When I added a multi-select dropdown that introduces an array, I started facing a strange problem. Even after using form.formRe ...

The alterations made to a single dropdown option are causing ripple effects across all other dropdowns

There is an add button that continuously adds a div container containing two dropdowns. The selection in one dropdown affects the data in the other dropdown. When the add button is clicked, a second div with both dropdowns is added. However, changing the ...

Dealing with JSON data in the format of `(Object object)` requires a specific approach

I originally encountered object object when attempting to display JSON API data in HTML. I then used keyvalue in *ngFor which allowed me to display the object, but I am wondering how I can access and display the entire JSON data? Here are the relevant cod ...

Implementing an extended interface as an argument in a function

Here is the code snippet for analysis: interface IUserData { FirstName: string, LastName: string, Email: string, Password: string } interface IState extends IUserData { isSuccess: boolean } const state: IState = { FirstName: &apo ...