Начальная загрузка начальной загрузки не передает значение 'term' и получает "Не удается найти другой поддерживающий объект" [object Object] 'типа' object ' - PullRequest
1 голос
/ 22 мая 2019

У меня есть приложение Angular 7.2.4 с Bootstrap 4.2.1. и я хотел бы вызвать бэкэнд-сервис для заполнения поля ввода автозаполнения, но у меня проблемы, даже несмотря на то, что у меня уже есть простая загрузка начальной загрузки.

HTML-страница:

<div class="form-group" [class.has-danger]="searchFailed">
    <label class="form-control-label" jhiTranslate="gatewayApp.legalAddress.fullAddress" for="field_fullAddress">Full Address</label>

    <ng-template #rt let-r="result" let-t="term">
        <ngb-highlight [result]="r.fullAddress" [term]="t"></ngb-highlight>
    </ng-template>

    <input type="text" class="form-control" name="fullAddress" id="field_fullAddress"
        [(ngModel)]="legalAddress.fullAddress" [ngbTypeahead]="searchAddress" placeholder="n°, nome via, città"
           [resultTemplate]="rt"
           [resultFormatter]="formatter"
           [inputFormatter]="formatter" />
    <span *ngIf="searching">searching...</span>
    <div class="form-control-feedback" *ngIf="searchFailed">Sorry, suggestions could not be loaded.</div>
</div>

Услуга:

type EntityArrayResponseType = HttpResponse<IAddress[]>;
 query(req?: any): Observable<EntityArrayResponseType> {
        console.log('[address.service.ts] query');
        const param = new HttpParams().set('searchCriteria', ADDRESS_OTHER_TYPE_CODE);
        return this.http.get<IAddress[]>(`${this.resourceUrl}/findbycriteria`, { params: param, observe: 'response' });
    }

Модель:

export interface IAddress {
    id?: number;
    addressType?: string;
    ...
    fullAddress?: string;
}

export class Address implements IAddress {
    constructor(
        public id?: number,
        public addressType?: string,
        ...
        public fullAddress?: string
    ) {}
}

Контроллер:

 searchAddress = (text$: Observable < string >) =>
        text$.pipe(
            debounceTime(300),
            distinctUntilChanged(),
            tap(() => (this.searching = true)),
            switchMap(term =>
                this.geoLocalizationService.query(term).pipe(
                    tap(() => (this.searchFailed = false)),
                    catchError(() => {
                        this.searchFailed = true;
                        return of([]);
                    })
                )
            ),
            tap(() => (this.searching = false))
        )

    formatter = (x: {fullAddress: string}) => x.fullAddress;

Две проблемы:

1) Заполнение поля ввода fullAddress вызывает searchAddress, но geoLocalizationService.query всегда получает пустое term и отправляет ноль в базовую базовую службу

2) Принудительное предоставление бэкэнд-сервисом результата в виде теста не приводит к отображению данных в поле ввода. Получаем это:

[geo-localization.service.ts] query geo-localization.service.ts:18:8
ERROR Error: "Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays."
    Angular 6
    View_NgbTypeaheadWindow_0 NgbTypeaheadWindow.html:5
    Angular 8
    node_modules ng-bootstrap.js:11024
    RxJS 41
    Angular 8
NgbTypeaheadWindow.html:5:4
    View_NgbTypeaheadWindow_0 NgbTypeaheadWindow.html:5
    Angular 5
    RxJS 5
    Angular 11
ERROR CONTEXT 
Object { view: {…}, nodeIndex: 4, nodeDef: {…}, elDef: {…}, elView: {…} }
NgbTypeaheadWindow.html:5:4
    View_NgbTypeaheadWindow_0 NgbTypeaheadWindow.html:5
    Angular 5
    RxJS 5
    Angular 11

Заранее спасибо!

==========

Решена точка 1 из-за глупого параметра. Теперь я могу правильно запустить бэкэнд-сервис, получив:

 [[{"place_id":48841472,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright","osm_type":"node","osm_id":3749006665,"boundingbox":["46...","46...","13...","13...."],"lat":"46....","lon":"13....","display_name":"---","class":"place","type":"house","importance":0.411,"address":{"house_number":"5","road":"---a","neighbourhood":"---","suburb":"---","city":"---","county":"---","state":"---","postcode":"---","country":"---","country_code":"---"}}]]

Теперь все еще с ошибкой пункта 2, я думаю, что с этим сервисом что-то не так:

    @Injectable({ providedIn: 'root' })
export class GeoLocalizationService {
    public resourceUrl = SERVER_API_URL + 'api/geolocalization/addresses';
    constructor(protected http: HttpClient) {}

    query(req?: any): Observable<EntityArrayResponseType> {
        console.log('[geo-localization.service.ts] query' + req);
        const param = new HttpParams().set('searchString', req);
        return this.http.get<IAddress[]>(this.resourceUrl, { 
        params: param, observe: 'response' });
    }
}

Может быть, это неправильный способ вернуть наблюдаемое. Должен ли я вернуть его, используя вместо этого подписку? В другом классе это работает:

provinces: IDomainBean [];

ngOnInit() {
    this.legalPersonService.findAllProvinces().subscribe(
        (res: HttpResponse<IDomainBean[]>) => {
            this.provinces = res.body;
        },
        (res: HttpErrorResponse) => this.onLegalFormTypeError(res.message)
    );
}

searchProvince = (text$: Observable< string >) =>
    text$.pipe(
        debounceTime(200),
        distinctUntilChanged(),
        map(term => term === '' ? []
            : this.provinces.filter(v => v.description.toLowerCase().indexOf(term.toLowerCase()) > -1).slice(0, 10))
    )

formatter = (x: {description: string}) => x.description;

1 Ответ

1 голос
/ 04 июня 2019

Почти решено ... теперь я могу запросить службу с этими изменениями:

1) "адрес" вместо "address.fullAddress" в ngModel:

<input type="text" class="form-control" name="fullAddress" id="field_fullAddress"
                       [(ngModel)]="address" [ngbTypeahead]="searchAddress" placeholder="n°, nome via, città"
                       [resultTemplate]="rt"
                       [resultFormatter]="formatter"
                       [inputFormatter]="formatter" />

2) Изменили услугу:

    searchAddress = (text$: Observable <string>) =>
    text$.pipe(
        debounceTime(300),
        distinctUntilChanged(),
        tap(() => (this.searching = true)),
        switchMap(term =>
            this.geoService(term).pipe(
                tap(() => (this.searchFailed = false)),
                catchError(() => {
                    this.searchFailed = true;
                    return of([]);
                })
            )
        ),
        tap(() => (this.searching = false))
    )

formatter = (x: {fullAddress: string}) => x.fullAddress;

geoService(term: String): Observable <IGeoAddress []> {
    if (term === '') {
        return of([]);
    }
    return this.geoLocalizationService.queryGeoAddress(term).pipe(
        map(res => {
            return res.body.map(add => {
                const addnew = new Address(
                    //  setting initial address values  
                    this.address.idSubject,
                    this.address.idContact,
                    add.latitude,
                    add.longitude,
                    ...

                );
                return addnew;
            });
        })
    );
}

Если это может помочь кому-то другому или его можно улучшить.

...