3

I'm trying to create a search page in angular, that queries results via Angulars $http Service and returns a defined object. The code looks similar to the tutorial the Angular documentation: https://angular.io/tutorial/toh-pt6#final-code-review.

However my app has a few key differences:

  • The object being returned is an object containing an array, as opposed to just an array.
  • My table in the view iterates over the array inside the object.

This is causing me an issue where the table in the view that iterates over this array throws a 'null' error before anything is searched, and therefore breaks the whole page from functioning properly

<tbody>
    <tr *ngFor="let email of (SearchResults$ | async).hits">
        <td><input type="checkbox" (change)="changeSelectedEmailsMap(email)" ></td>
        <td>{{email._source.from}}</td>
        <td>{{email._source.recipient}}</td>
        <td>{{email._source.date | date: 'dd/MM/yyyy hh:mm:ss'}}</td>
        <td>{{email._source.subject}}</td>
        <td><a routerLink="/detail/{{email.id}}" class="btn btn-outline-info btn-sm" role="button">View</a></td>
     </tr>
 </tbody>

For now, this is the only part of the page using these results, however it will be using other variables in SearchResults$

I have tried hiding the table entirely until results came in, using *ngIf="SearchResults$ !== null" on the entire table. However it still throws a null error once results come in and the table displays, leading me to believe the object isn't getting completely filled before the table takes a gander.

Is there any way to have the table only check hits when the variable exists?

Component.ts:

export class RepositorySearchComponent implements OnInit {

  @Input() repository: Repository;

  SearchResults$: Observable<EmailSearchResult>;

  private searchTerms = new Subject<string>();

  constructor(private emailService: EmailService) { }

  search(term: string){
    this.searchTerms.next(term);
  }


  ngOnInit() {
    this.SearchResults$ = this.searchTerms.pipe(
      debounceTime(300),

      distinctUntilChanged(),

      switchMap((term: string) => this.emailService.search(term, this.repository.id))
    );
  }
}

1 Answer 1

3

Use safe navigation operator as follows:

  <td>{{email?._source?.from}}</td>

Note the two operators used there, one is after email and the other is after _source

Use the safe navigation operator on all <td> tags where you use the async data.

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

1 Comment

I wasn't aware of the safe navigation operator.I had to stick it on 'hits' before it worked, but it seems to be doing the trick for me. Thanks!

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.