0

I have a function that makes an HTTP request. I want that function to make the request, change a variable's value inside the subscribe and print the variable to the console.

However, I keep getting the variable's original value whenever I print it.

I debugged my code and I noticed that my function executes two times.

On the first time, the code inside the subscribe is not executed and because of that the console.log(test) prints Output: true.

On the second time, the code inside the subscribe gets executed but the console.log(test) doesn't.

Here is my code:

MyComponent.component.ts

private searchTest(value) {
  let test: boolean = true;
  this.rest.getOrderByNumber(value).subscribe((orderNrData: {}) => {
    if (Object.entries(orderNrData).length !== 0) {
      test = false;
    } else { 
      test = false;
    }
  }, error => {
    test = false;
  });
  console.log(`Output: ${test}`);
}

MyComponent.component.html

<div class="row">
  <div class="col-2"></div>
  <div class="col-8 search-div">
    <mat-form-field class="search-form-field" appearance="outline" [formGroup]="searchForm">
      <mat-label>Search</mat-label>
      <input matInput class="search-input" id="search-input-id" placeholder="Ex: EU030327" formControlName="inputForm" #searchInput>
    </mat-form-field>
    <span matSuffix>
      <button mat-flat-button class="search-btn" color="accent"
        (click)="searchTest(searchInput.value)"><i class="fa fa-search"></i></button>
    </span>
  </div>
  <div class="col-2"></div>
</div>

Basically, what I'm trying to achieve is to be able to make an HTTP request and change a variable's value so I can use it on another part of the code (like on an ngIf).

  1. Why do I get this behavior?
  2. How I can make the rest of the code wait for the HTTP request to be executed?

EDIT:

I have updated my functions to use callbacks, so now I have this:

MyComponent.component.ts

teste: boolean = true;

searchTest(value){
  this.test(this.test1, value, this);
}

test(callback, value, self){
  callback(value, self);
}

test1(value, self){
  self.rest.getOrderByNumber(value).subscribe((orderNrData: {}) => {
    if (Object.entries(orderNrData).length !== 0) {
      self.teste = false;
    } else { 
      self.teste = false;
    }
  }, error => {
    self.teste = false;
  });
}

MyComponent.component.html

<div class="row">
  <div class="col-2"></div>
  <div class="col-8 search-div">
    <mat-form-field class="search-form-field" appearance="outline" [formGroup]="searchForm">
      <mat-label>Search</mat-label>
      <input matInput class="search-input" id="search-input-id" placeholder="Ex: EU030327" formControlName="inputForm" #searchInput>
    </mat-form-field>
    <span matSuffix>
      <button mat-flat-button class="search-btn" color="accent"
        (click)="searchTest(searchInput.value)"><i class="fa fa-search"></i></button>
    </span>
  </div>
  <div class="col-2"></div>
</div>

<p *ngIf="!teste">
  This is the error!
</p>

Now I have another problem... The <p> only appears when I press my button twice or if I hover my mouse pointer over a different component (this is a really weird and new behavior for me).

My page has a component with a search input (the one I'm currently in) and a component with a table that shows the data from the HTTP response.

What's the problem with my code?

Hrishi
  • 1,210
  • 1
  • 13
  • 25
H. Soares
  • 203
  • 5
  • 22
  • 2
    The code inside `subscribe(...)` executes ***sometime later***. That's why it's written as a *callback function.* That's the basic working behind *asynchronous execution.* – deceze Apr 08 '19 at 12:45
  • I get why it works like that but what if I need to update some global variable after the HTTP response was received? I need to set a global variable to true if the response is invalid but like the example I posted, I'm unable to do it. – H. Soares Apr 08 '19 at 12:57
  • 1
    You never "have to", because you can't. All code dependent on that asynchronous value will have to await it asynchronously too. – deceze Apr 08 '19 at 12:59
  • That is not making sense to me... Imagine I have a variable that is set to false whenever an HTTP response is invalid, and I have a `
    ` that only shows if that variable is set to false. Now, initially this variable is set to true so the `
    ` is correctly hidden, however when I execute that HTTP response and obtain an invalid response the `
    ` will never show up because the code is asynchronous and the variable won't get set to false... Is there no solution to this? I can update my original post with an example if you want
    – H. Soares Apr 08 '19 at 13:08
  • 1
    You can show or hide the element *when the HTTP response returns with an answer*. It doesn't matter if your code waits until then. Read the duplicates. You may not like it, but this is how you do things in Javascript. – deceze Apr 08 '19 at 13:09
  • I've updated my post with a new problem... I tried using callbacks but I still have no luck, however I'm experiencing a strange behavior. The `

    ` with the error message only shows when I click on my search button twice or when my mouse pointer hovers over a different component (further explained in my post)

    – H. Soares Apr 08 '19 at 13:33

0 Answers0