I am consuming a backend service in Angular to validate a reference number. However I am getting an error in the browser console. I am a newbie in Angular and I don't know what could be what is happening, any help I appreciate.
I consume the API from this service:
payments.online.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import {PagoOnlineModel} from '@app/pagos-online/pagos-online.model';
const routes = {
base: `${env.apiUrl}/pagos_online/`,
};
@Injectable({
providedIn: 'root'
})
export class PagosOnlineService {
userData;
constructor(private httpClient: HttpClient) {
this.userData = {};
this.today = new Date();
}
validarReferencia(numero_referencia: string): Observable<any> {
return this.httpClient.post(`${routes.base}validar_codigo_bancolombia/`, numero_referencia);
}
}
I use that class in the following function
modal-online-payments.component.ts
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {FormGroup, FormBuilder, Validators, FormControl} from '@angular/forms';
import {CustomValidators} from '@app/core/validators';
import createNumberMask from 'text-mask-addons/dist/createNumberMask';
import { formatDate } from '@angular/common';
import { environment as env } from '@env/environment';
import { HttpClient } from '@angular/common/http';
import {PqrsService} from '@app/pqrs/pqrs.service';
import { PagosOnlineService } from '@app/pagos-online/pagos-online.service';
const numberMask = createNumberMask ({
prefix: '$',
thousandsSeparatorSymbol: '.',
});
@Component({
selector: 'app-modal-pagos-online',
templateUrl: './modal-pagos-online.component.html',
})
export class ModalPagosOnlineComponent {
// Masks
public moneyMask = numberMask;
@Input() activate = false;
@Input() isLoading = false;
@Output() onComplete: EventEmitter<any> = new EventEmitter<any>();
@Output() onCancelSubmit: EventEmitter<any> = new EventEmitter<any>();
ValorPagoForm: FormGroup;
cargando = false;
productos: any = [
{'codigo': '', 'nombre': '- Seleccione -'},
{'codigo': '1', 'nombre': 'Recaudo 1'},
{'codigo': '2', 'nombre': 'Recaudo 2'},
{'codigo': '3', 'nombre': 'Recaudo 3'},
];
constructor(private formBuilder: FormBuilder,
private httpClient: HttpClient,
private pagosOnlineService: PagosOnlineService) {
this.createForm();
}
completeSubmit() {
this.isLoading = false;
// this.onCancelSubmit.emit();
this.onComplete.emit();
}
cancelSubmit() {
this.valor_pago.setValue('');
this.numero_referencia.setValue('');
this.activate = false;
this.onCancelSubmit.emit();
}
referenciaValidator(control: FormControl) {
this.pagosOnlineService.validarReferencia(this.numero_referencia.value)
.subscribe(
data => {
this.numero_referencia.errors.invalidReferencia = data['estado_validacion'];
},
error => {
this.numero_referencia.errors.invalidReferencia = false;
}
);
}
private createForm() {
this.ValorPagoForm = this.formBuilder.group({
valor_pago: ['', [Validators.required]],
numero_referencia: ['', [CustomValidators.number, Validators.required, this.referenciaValidator]],
producto_pagar: ['', Validators.required],
});
}
get valor_pago() { return this.ValorPagoForm.get('valor_pago'); }
get numero_referencia() { return this.ValorPagoForm.get('numero_referencia'); }
get producto_pagar () { return this.ValorPagoForm.get('producto_pagar'); }
unmaskNumber(val) {
return val.replace(/\D+/g, '');
}
}
And this is the html section where I make use of the function
<div class="control">
<div class="col-md- 8col-sm-8 col-xs-8" align="center">
<label class="label is-small is-required">Referencia de pago</label>
<input type="text" placeholder="Ingrese el número de referencia de pago"
class="input is-small primaryFields" tabindex="2"
formControlName="numero_referencia" maxlength="20"
[ngClass]="{ 'is-danger': numero_referencia.invalid && (numero_referencia.dirty || numero_referencia.touched) }"
(blur)="referenciaValidator()">
<div class=""></div>
</div>
<div class="control-errors" align="center"
*ngIf="numero_referencia.invalid && (numero_referencia.dirty || numero_referencia.touched)">
<p class="help is-danger" *ngIf="numero_referencia.errors.required">
El número de referencia es obligatorio
</p>
<p class="help is-danger" *ngIf="numero_referencia.errors.number">
El número de referencia debe ser numérico
</p>
<p class="help is-danger" *ngIf="numero_referencia.errors.invalidReferencia">
La referencia no se encuentra registrada en el sistema
</p>
</div>
</div>
And this is the error it is generating me
I appreciate the help you can give me, if my doubt is not clear, please inform me. I really need to fix this.
Problem
The problem is in the
this
inside of the functionValidador
, since it is executed in anothercontext
(even though the functionreferenciaValidator
is in the same file). Which means itthis.pagosOnlineService
doesn't exist inside the function.In short, the
this
inside of functions declared asValidators
is not the same as the outside of them.Solution
To fix this you can assign the context
this
of your component to that of the function like this:With
bind
you indicate the context that your validator will have.Observation
Inside your function
referenciaValidator
you can use the variablecontrol.value
instead of referencingthis.numero_referencia.value
as it is the same(If the code inside the validating function is correct it should work)
Cheers! I hope it helps.
Are you sure you declared the service correctly in the module? The declaration and call to the service are correct, so we only have to validate that it is correctly registered in the corresponding module.
Although I am seeing that you have "providedIn: 'root'" declared, so what I told you above would not be necessary... Could you verify that it is passing through the constructor?
Another thing... That may be silly but... The "this" will not be referring to the input which is calling the function, right?
Hope that helps, best regards!