0
  1. I have a search bar in app.component.ts that has an input value.

  2. results.component.ts is embedded with a router-outlet in app.component.html

  3. When results.component.ts is the current activated route, the search works fine and so do the results.

  4. However, if someone clicks on a result, results.component.ts is replaced with a different component view detail.component.ts (it provides them with more information about the result.)

  5. On detail.component.ts I have a "back to results" link setup with a routerLink='/'. And mind you, the search query is still present in the search bar because that view never gets replaced.

  6. When this back button is clicked, results.component.ts reloads and fires ngOnInit.

The problem: I can't access the value of the search string in app.component.ts from results.component.ts ngOnInit to repopulate the results. I've tried almost everything I can think of.

I already have a service built, but I don't know how to set it up to communicate that value, if that is the solution.

Updated with code

app.component.html

//other html
<input placeholder="What do you want to learn?" name="searchStr" [(ngModel)]="searchStr" (keyup.enter)="searchCourse($event)">

interaction-service.service.ts:

import { Injectable } from '@angular/core';
import { Subject }    from 'rxjs/Subject';


@Injectable()
export class InteractionService {

   // Observable string sources
  private searchStr = new Subject<string>();

  // Observable string streams
  searchStr$ = this.searchStr.asObservable();

  sendString(searchString: string) {
    this.searchStr.next(searchString);
  }

}

app.component.ts:

//other imports
import {InteractionService} from './interaction-service.service';

@Component({ 
  selector: 'my-app',
  templateUrl: 'app.component.html',
  providers: [CourseService, InteractionService]
})

export class AppComponent implements OnInit { 

    searchStr: string;

    constructor(private _courseService: CourseService, private _interactionService: InteractionService, private router: Router) {

    }

    ngOnInit() {

    }

    searchCourse(event) {
        this._interactionService.sendString(event.target.value);
        this.router.navigateByUrl('/');
    }

}

course-listings.component.ts (I referred to this as results above)

// other imports
import {Subscription} from 'rxjs';
import {InteractionService} from '../interaction-service.service';

@Component({
  selector: 'app-course-listings',
  templateUrl: './course-listings.component.html',
  providers: [CourseService],
})

export class CourseListingsComponent implements OnInit {

    //some other properties defined
    @Input() searchStr: string;
    subscription: Subscription;

    constructor(private _courseService: CourseService, private _interactionService: InteractionService) {

         this.subscription = this._interactionService.searchStr$.subscribe(
    courses => {
             this.searchStr = courses;

             // code for returning results here..

         }
  );

    }

    ngOnInit() {

    }


}
1
  • The value is not accessible. The problem cannot reproduce. Commented Nov 16, 2016 at 23:07

1 Answer 1

1

Your right that you want to use a service. Services are singletons so setting in one component and getting from another will return the passed value.

To get a service to work you need to create the service then add it to your app module. Then in the constructor for your component you add it so the dependency injection can add it to the component for you. The constructor looks like this.

constructor( private router: Router){}

Each component should have a reference in its constructor and the service singleton is shared.

interaction-service.service.ts:

import { Injectable } from '@angular/core';
import { Subject }    from 'rxjs/Subject';


@Injectable()
export class InteractionService {
    sharedString = "";
}

app.component.ts:

import {InteractionService} from './interaction-service.service';

@Component({ 
  selector: 'my-app',
  templateUrl: 'app.component.html',
  providers: [CourseService, InteractionService]
})

export class AppComponent implements OnInit { 

constructor(private _courseService: CourseService, private     _interactionService: InteractionService, private router: Router) {

    }

ngOnInit() {
    this.__interactionService.sharedString = "Some value";
}

searchCourse(event) {
    this._interactionService.sendString(event.target.value);
    this.router.navigateByUrl('/');
}

}

I'm going to leave the rest of the code out. The above example should be enough. Simply make the injected interaction service available and set and get the values at will. The service values will persist until there is a browser context change. Last thing I want to mention is when routing call the router like this

this.router.navigate(["url", someParam]);

this will preserve context and not cause a browser context switch when moving between components.

Sign up to request clarification or add additional context in comments.

2 Comments

Okay great, that's what I thought. I updated the original post with my basic coding structure. Could you elude to how I would share that <input value through the service? Thanks a lot.
Thanks man! Got it to work by sticking your suggestion from ngOnInit() to searchCourse(event) (the method called when a search is performed).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.