1
I’m trying to build a dynamic combo with Angular, but I’m not succeeding, I can implement with static values, but I was unsuccessful when I went to adapt it with my Java API that has database connection.
My goal is to load a dropdown list of a state of Brazil so it can automatically load the second dropdown list of the cities of Brazil corresponding to that state of Brazil that was selected in the first dropdown list.
OBS: the data that are in my local database I enter the city and states with Insert in the database.
Through facebook found this example of dynamic combo with static data to understand what I need:
The practical effect is in the 21 minutes and 38 seconds of this video.
The example with static data is getting this kind of feedback;
this.cidadesService.buscarEstados().subscribe(result => {
console.log(this.estados = result);
});
Stayed like this;
And with cities it was like this;
buscarCidades() {
this.cidadesService.buscarCidadePorUF(
this.uf)
.subscribe(result => {
console.log(this.estados = result);
});
}
Stayed like this:
And so:
The repository with static data said, Click Here
Beauty but when I went to adapt it to take data from my Java API I did not succeed, is this error message that is giving.
My component was like this;
import { Estado, Cidade } from './../../core/model';
import { CidadesService } from './../cidades.service';
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-cidades-pesquisa',
templateUrl: './cidades-pesquisa.component.html',
styleUrls: ['./cidades-pesquisa.component.css']
})
export class CidadesPesquisaComponent implements OnInit {
codigo: string;
cidadePorEstado: string;
estados = new Estado();
cidades = new Cidade();
constructor(
private cidadesService: CidadesService
) { }
ngOnInit() {
this.cidadesService
.buscarEstados()
.subscribe(result => this.estados = result);
this.pesquisarCidades();
this.pesquisarEstado();
}
pesquisarCidades() {
this.cidadesService.listarTodasCidades()
.then(() => null);
}
pesquisarEstado() {
this.cidadesService.listarTodosEstados()
.then(() => null);
}
buscarCidades() {
this.cidadesService.buscarCidadePorUF(
this.codigo)
.subscribe(result => this.cidades = result);
}
}
The job was like this:
import { Cidade, Estado } from './../core/model';
import { Injectable } from '@angular/core';
import { Http, URLSearchParams, Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
@Injectable()
export class CidadesService {
cidadesUrl = 'http://localhost:8080/cidades';
estadosUrl = 'http://localhost:8080/cidades/estados';
constructor(private http: Http) { }
listarTodasCidades(): Promise<any> {
return this.http.get(this.cidadesUrl)
.toPromise()
.then(response => response.json());
}
listarTodosEstados(): Promise<any> {
return this.http.get(this.estadosUrl)
.toPromise()
.then(response => response.json());
}
buscarEstados(): Observable<any> {
return Observable.of([
this.listarTodosEstados()
]);
}
buscarCidadePorUF(codigo: string): Observable<any> {
if (codigo === 'codigo_estado') {
return Observable.of([
this.listarTodasCidades()
]);
} else {
return Observable.of([ ]);
}
}
}
And my page was like this;
<div class="container">
<select name="estado" id="estado" [(ngModel)]="codigo" (change)="buscarCidades()">
<option *ngFor="let estado of estados" [value]="estado.codigo">{{estado.nome}}</option>
</select>
<select name="cidade" id="cidade" [(ngModel)]="cidadePorEstado">
<option *ngFor="let cidade of cidades" [value]="cidade.cidadePorEstado">{{cidade.nome}}</option>
</select>
<br>
<br>
<br> UF Selecionada: {{codigo}}
<br>
<br> IBGE Selecionado: {{cidadePorEstado}}
</div>
I did some testing and my Angular API is achieving State and Cities GET see;
listarTodasCidades(): Promise<any> {
return this.http.get(this.cidadesUrl)
.toPromise()
.then(response => {
console.log(response.json());
});
}
Stayed like this:
And of States:
listarTodosEstados(): Promise<any> {
return this.http.get(this.estadosUrl)
.toPromise()
.then(response => {
console.log(response.json());
});
}
was like this;
Notice he’s calling twice;
My repository looks like this, Click here
I don’t know how to solve this problem, I accept suggestions;
My database looked like this:
cities
State
============UPDATING=======================
I was instructed to make the following modifications;
The component:
import { Estado, Cidade } from './../../core/model';
import { CidadesService } from './../cidades.service';
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-cidades-pesquisa',
templateUrl: './cidades-pesquisa.component.html',
styleUrls: ['./cidades-pesquisa.component.css']
})
export class CidadesPesquisaComponent implements OnInit {
codigo: string;
cidadePorEstado: string;
estados: Estado[] = [];
cidades: Cidade[] = [];
constructor(
private cidadesService: CidadesService
) { }
ngOnInit() {
// Aqui vc só precisa chamar a consulta de estados para carregar o select de estado e
// a pesquisa de cidade só deve ocorrer no change do select de estado
this.cidadesService
.buscarEstados()
.subscribe(result => this.estados = result);
// então esses dois métodos não existe
// this.pesquisarCidades();
// this.pesquisarEstado();
}
/*
Não precisa desses métodos
pesquisarCidades() {
this.cidadesService.listarTodasCidades()
.then(() => null);
}
pesquisarEstado() {
this.cidadesService.listarTodosEstados()
.then(() => null);
}*/
buscarCidades() {
this.cidadesService.buscarCidadePorUF(this.codigo)
.subscribe(result => this.cidades = result);
}
}
The service;
import { Cidade, Estado } from './../core/model';
import { Injectable } from '@angular/core';
import { Http, URLSearchParams, Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class CidadesService {
cidadesUrl = 'http://localhost:8080/cidades';
estadosUrl = 'http://localhost:8080/cidades/estados';
constructor(private http: Http) { }
buscarEstados(): Observable<any> {
return this.http.get(this.estadosUrl);
}
buscarCidadePorUF(codigo: string): Observable<any> {
// Aqui seu endpoint tem que receber o parâmetro codigo do estado e já retornar filtrado, ficaria assim:
return this.http.get(`${this.cidadesUrl}&codigoEstado=${codigo}`);
// Agora cara seu endpoint não estiver preparado para filtrar as cidades por estado vc usa o código abaixo e la no seu componente de cidades-pesquisa vc tem que filtrar por estado;
//return this.http.get(this.cidadesUrl);
}
}
I’m facing the following mistake:
See more detail:
Then find that my problem misses this:
EXCEPTION: Response with status: 200 Ok for URL:
So I found this site to solve my problem:
Because of this I decided to install it with the command below;
npm install jsonp
See the code first:
import { Cidade, Estado } from './../core/model';
import { Injectable } from '@angular/core';
import { Http, URLSearchParams, Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class CidadesService {
cidadesUrl = 'http://localhost:8080/cidades';
estadosUrl = 'http://localhost:8080/cidades/estados';
constructor(private http: Http) { }
buscarEstados(): Observable<any> {
return this.http.get(this.estadosUrl);
}
buscarCidadePorUF(codigo: string): Observable<any> {
// Aqui seu endpoint tem que receber o parâmetro codigo do estado e já retornar filtrado, ficaria assim:
return this.http.get(`${this.cidadesUrl}&codigoEstado=${codigo}`);
// Agora cara seu endpoint não estiver preparado para filtrar as cidades por estado vc usa o código abaixo e la no seu componente de cidades-pesquisa vc tem que filtrar por estado;
//return this.http.get(this.cidadesUrl);
}
}
And the code after the modification:
import { Cidade, Estado } from './../core/model';
import { Injectable } from '@angular/core';
import { Http, URLSearchParams, Headers, Jsonp } from '@angular/http';// modificação foi aqui!
import { Observable } from 'rxjs/Observable';
@Injectable()
export class CidadesService {
cidadesUrl = 'http://localhost:8080/cidades';
estadosUrl = 'http://localhost:8080/cidades/estados';
constructor(private jsonp: Jsonp) { }// modificação foi aqui!
buscarEstados(): Observable<any> {
return this.jsonp.get(this.estadosUrl);// modificação foi aqui!
}
buscarCidadePorUF(codigo: string): Observable<any> {
return this.jsonp.get(`${this.cidadesUrl}&codigoEstado=${codigo}`); // modificação foi aqui!
}
}
Then he made that other mistake:
From what I understand, I may be mistaken, he wants me to change HttpModule
for JsonpModule
, but if I do this I will have to change my entire project to use Httpmodule, it’s kind of complicated because my project is a little big.
I’m taking an Angular-4 course and I’m on duty
HTTP
, I could try to help you if you’d lower your question and try to focus on the problem itself.– Marconi
i am using vscode
– wladyband
Look at the little I’ve learned in this course: Building Web Applications with the New Angular 4 used only one
modulo
(which is bootstrap from my application)and you are using several modules(I haven’t gotten to that part yet). My opinion (I don’t know if it’s the right one) in place of its modules should be components. The cool of you to take the course that besides the teacher explain well it shows you how to check errors to every modification in the code, which incidentally yours is full. Sincerely I recommend you discard everything and redo, do not hesitate to disagree!– Marconi
The fact of having several modules is because I am with a very evolved project and the organization of my project is following a good practice of programming in relation to the organization of the project, as I could not put the complete project because it could confuse the person who could help me solve only put a part of my project in the pasture, I am grateful to show me a good reference course but unfortunately I do not have money to make the course, I recognize that it is a good course, if I could I really plan, but I am not in financial condition to take the course.
– wladyband