Information will only be displayed after the button has been double-clicked

After a month of experimenting with Angular and being relatively new to web development, I've encountered an issue that I hope someone can help me with. In my simple Angular application, I have a button called roomSearch() which sends form data to an MVC Web API. The data retrieved from the API is then displayed on the HTML page by the Angular component.

The problem is that I always have to click the button twice in order to see the result. It never works on the first click, and I'm struggling to understand why.

Here is the code snippet:

HTML Section:

<form #roomForm="ngForm" class="coupon-form" (ngSubmit)="onSubmit(roomForm)">
  <div class="row">
    ...
  </div>

  <div class="form-group">
    <button type="button" (click)="roomSearch(roomForm)" class="btn btn-lg btn-block btn-info"><i class="fa fa-floppy-o" aria-hidden="true"></i> Submit</button>
  </div>
</form>

...

Component File:

 show: boolean;

 ngOnInit() {
    this.show = this.roomService.show;
  }

  roomSearch(form: NgForm)
  {
    this.show = this.roomService.getRoomList(form.value.startDate, form.value.endDate);
  }

Service File:

 constructor(private http: Http) {
      this.show=false;
    } 

getRoomList(startDate: string, endDate:string){
    ...

The issue arises when I try to log the this.roomList on the console. It initially shows as undefined on the first click but displays the correct value on the second click. Can anyone point out what I might be doing wrong here?

Answer №1

Great job on organizing your code! It was really easy to follow.

The issue you're encountering is related to asynchronous behavior.

Angular utilizes Observables when making HTTP calls, which means the result of the call will come later, not immediately after the request is made.

In your specific case, here's what's happening:

this.http.get(this.finalUrl)
.map((data: Response)=>{
  return data.json() as Room[];
}).toPromise().then(x =>{
  this.roomList = x;
});

console.log(this.roomList);

You are logging `undefined` because you're not waiting for the promise to be resolved, meaning you're trying to access `this.roomList` before it has been assigned a value.

To fix this issue, consider the following approach:

processRequest(roomList: Room[]) {
  // Your processing logic goes here
}

// Remove everything after this line in your existing code

return this.http.get(this.finalUrl)
  .map((data: Response) => {
    return data.json() as Room[];
  }).toPromise().then(x => {
    return Promise.resolve(this.processRequest(x))
  });

Lastly, in your component, make sure to update the method to:

roomSearch(form: NgForm)
{
  this.roomService.getRoomList(form.value.startDate, form.value.endDate).then(show => this.show = show);
}

In summary, fetch the rooms via HTTP request, wait for the response, process the data using `processRequest`, and then bind the processed result to the appropriate variable in your component.

If you need further clarification, don't hesitate to ask!

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

What is the process for displaying a custom component within a parent view component?

I am seeking to incorporate a custom component within mat-option. Below is the code snippet from my parent component: <mat-option *ngFor="let option of options" [value]="option.value"> HERE I WOULD LIKE TO INJECT SOME COMPONE ...

Issue encountered while attempting to utilize a basic redux reducer to define a boolean value, regarding a mismatch in overrides

Currently, I am working on a project to enhance my understanding of Redux and Typescript. I am still navigating through the learning curve in this area. Based on what I have learned from a book, I have established a "slice" that includes definitions for r ...

Material UI offers a feature that allows for the grouping and auto-completion sorting

I am currently utilizing Material UI Autocomplete along with React to create a grouped autocomplete dropdown feature. Here is the dataset: let top100Films = [ { title: "The Shawshank Redemption", genre: "thriller" }, { title: " ...

Typeorm retrieve values of fields depending on their datatype

I have a TypeORM entity called SuperResource @Entity() export class SuperResource extends BaseEntity { @PrimaryGeneratedColumn() id: number; @OneToOne(() => Resource, {cascade: true, eager: true}) @JoinColumn() resource: Resource @Column({ ...

The error message TS2322 occurs due to the inability to assign the type 'Observable<{}[]>' to 'Observable<Archive[][]>'

While upgrading from Angular 5.2.11 to 7.3.9, I encountered a types issue that was not present in the previous version of Angular. After fixing the import for forkJoin, the code snippet below now throws an error: ERROR in src/app/reports/report-measureme ...

Upon closing the browser, the Angular ngx-cookie-service data disappears

Currently, I am working on setting a cookie using ngx-cookie-service so that I can retrieve it later as needed. Everything seems to be functioning properly as the code works well when refreshing the page, and the cookie is visible in Chrome developer tool ...

angular2: The element 'Validators' is not recognized

When working with Angular2, I encountered an error in Visual Studio Code that is displayed with the following message: enter image description here Here is the content of my tsconfig.json file: { "compilerOptions": { "target": "es5", "module" ...

What method can be used to modify the src attribute of an <img> tag given that the id of the <img> element is known?

My challenge involves displaying an array of images using a *ngFor loop. itemimg.component.html <div *ngFor="let itemimg of itemimgs" [class.selected]="itemimg === selectedItemimg" (click)="onSelect(itemimg)"> <img id="{{itemim ...

What is the technique for an Angular application to lazily load an angular module from another application?

I am currently working on lazy loading an Angular module into the main Angular application from a separate application. In the main application, the routes are configured as shown below: const routes: Routes = [ { path: 'admin', loadChildren: ...

Loop through an enum in ion-select

How can I use ngModel to iterate through an enum with ion-select? export enum EducationLevel { ILLITERATE = "Illiterate", 1_TO_3_YEARS = "1 to 3 years", 4_TO_7_YEARS = "4 to 7 years", MORE_THAN_8_YEARS = "more than 8 years" } class Person ...

What is the reason `addEventListener` does not work with a class method?

Recently, I discovered that the listener passed to addEventListener can actually be an object with a handleEvent function instead of just a callback function (here). However, I encountered an issue when trying to use handleEvent as a class method: class F ...

Showing JSON data as a list in Angular 7

I'm encountering a problem trying to display JSON data in a list format. It seems like something is missing because the data isn't showing up. Below is the code I've been using: Service: getData() { this.http.post('http://localho ...

Guide to transitioning from Angular 4 to Angular 7: incorporating 'URLSearchParams' and 'RequestOptions'

I am in the process of updating my project from Angular 4 to Angular 7. I have successfully switched from using http to httpClient and changed to common/http as well. However, I am inexperienced with Angular and unsure how to convert urlSearchParams and ...

What is the best way to merge multiple *ngifs in Angular?

Hey there, I am looking to create a conditional statement with three different outputs that will be displayed in a table. Currently, this is the code snippet I have: <td><div *ngIf="todo.diffDays >90">ninety</div> </td> I want ...

showing pop-up notification in Angular

I am utilizing the ngx-alert service to show an error message if the supplied credentials do not match any user account in my database. This is my current process: if (this.check.data.length == 0) { this.alert.danger('User does not exist' ...

Determining the inner type of a generic type in Typescript

Is there a way to retrieve the inner type of a generic type in Typescript, specifically T of myType<T>? Take this example: export class MyClass { myMethod(): Observable<{ prop1: string, ... }> { .... } } type myClassReturn = ReturnTy ...

Confirm the existence of a non-null value

One of the functions I have implemented is designed to remove null values from an array that is passed as input. This function also provides an optional transform functionality, allowing the user to modify the elements of the array into a custom format if ...

adjusting the template of the @Component programmatically

The template I am using is generated dynamically based on the intricate rules defined in the Java layer. I am wondering if there is a method to dynamically assign or modify a component's template during ngOnInit or any other suitable point in the cod ...

Merging and modifying numerous http requests in Angular using the RxJS operator forJoin

I have been working on combining multiple http requests using the forkJoin rxjs operator. fetchUsers() { const userIds = [1, 2, 3]; const url = 'https://jsonplaceholder.typicode.com/users'; forkJoin(userIds.map(id => this.http.get ...

Guide on how to create a promise with entity type in Nest Js

I am currently working on a function that is designed to return a promise with a specific data type. The entity I am dealing with is named Groups and my goal is to return an array of Groups Groups[]. Below is the function I have been working on: async filt ...