Я был в процессе миграции кодовой базы с Angular 4.x на 5.x, и я столкнулся со странной проблемой. У меня есть сервисная функция, которая предназначена для возврата списка объектов во внешний интерфейс, который я затем массирую в определенный формат данных. Я знаю, что мне нужно сохранить отображение, но я немного раздражен, что он возвращает только простые строковые данные.

Исходная функция: (используя Http из @angular/http, только что переименованный в HttpClient)

    public GetVendors(showAll = true, screenArea: number = 0): Observable<Array<SelectModel>> {
        let link = AppSettings.API_COMMON_VENDORS;
        let params: URLSearchParams = new URLSearchParams();
        params.set('showAll', showAll.toString());
        params.set('screenArea', screenArea.toString());

        let requestOptions = new RequestOptions();
        requestOptions.search = params;

        return this.httpClient.get(link, requestOptions).map(response => {
            let result = JSON.parse(response.json());
            let list = new Array<SelectModel>();
            let vendors: Array<any> = result;

            vendors.forEach(vendor => {
                list.push(this.CreateSelectModel(vendor));
            });

            return list;
        });
    }

И после извлечения ВСЕХ кода Http, вот функция снова, используя HttpClient из @angular/common/http

    public GetVendors(showAll = true, screenArea: number = 0): Observable<Array<SelectModel>> {
        let link = AppSettings.API_COMMON_VENDORS;
        let params: HttpParams = new HttpParams()
            .set('showAll', showAll.toString())
            .set('screenArea', screenArea.toString());

        return this.httpClient.get<Array<any>>(link, {params}).map(response => {
            let list = new Array<SelectModel>();

            response.forEach(vendor => {
                list.push(this.CreateSelectModel(vendor));
            });

            return list;
        });
    }

Проблема в том, что это своего рода побеждает цель нового клиента, разбирающего json для меня. Объект response представляет собой строку, представляющую JSON данных, которые я запросил, но он все еще находится в строковой форме, а не в типе, определенном в вызове get<>().

Что я здесь не так делаю? не должно ли это быть проанализировано уже?

Пример данных ответа Сетевые инструменты A'la в Chrome Dev Tools: введите описание изображения здесь

Образец тела ответа:

enter image description here

Скриншот Dev Tools со значением response введите описание изображения здесь

Бэкэнд (C #) отвечает так:

      [HttpGet]
        public JsonResult Vendors(bool showAll = false, int screenArea = 0)
        {
            var vendors = _commonBL.GetVendorsSlimForUser(UserModel, UserModel.CustomerId, showAll, screenArea);

            return GetJson(vendors);
        }

Так он работал до миграции Http => HttpClient, и он работал с ОДНИМ JSON.parse() Данные в строке возврата - это просто стандартные List<T>

0
Chris Rutherford 24 Окт 2019 в 20:46

2 ответа

Лучший ответ

Вот как должен выглядеть необработанный ответ для ваших данных :

[{"Id":1234,"Name":"Chris Rutherford"}]

Но вот как это на самом деле выглядит:

"[{\"Id\":1234,\"Name\":\"Chris Rutherford\"}]"

Итак, где-то в коде вашего сервера вы применили кодировку JSON дважды. Как только вы исправите это, HttpClient поступит правильно.

0
Sean Bright 24 Окт 2019 в 18:27

Я бы процитировал ответ из этой темы. Надеюсь, что это проливает некоторый свет на то, как все работает, прочитайте его полностью, это просветило меня, что его нелегко найти.

TypeScript проверяет интерфейс объекта только во время компиляции. Любой объект, который код выбирает во время выполнения, не может быть проверен TypeScript.

Если это так, то такие вещи, как HttpClient.Get не должны возвращать Observable типа T. Он должен возвращать Observable типа Object, потому что это то, что фактически возвращается. Попытка заявить, что он возвращает T, когда возвращает Object, вводит в заблуждение.

В документации по возврату клиент говорит следующее:

@ вернуть Observable тела как тип T.

На самом деле в документации должно быть сказано:

@ вернуть Observable тела, которое может быть T. Вы не получите T обратно. Если бы вы вернули Т, было бы на самом деле быть T, но это не так.

0
Kristóf Tóth 24 Окт 2019 в 18:14