Angular4 Injecting Service class - код в конструкторе не завершен при вызове метода службы?

Я пытаюсь попасть в Angular4/5. У меня есть подключение к службе CMS под названием Sanity (https://www.sanity.io/). Проблема, с которой я сталкиваюсь, заключается в том, что эта служба внедряется в класс ProductsComponent, и я вызываю методы в этой службе в методе компонента ngOnInit. Однако я получаю следующую ошибку, когда пытаюсь перекомпилировать с помощью команды ng serve:

ERROR in src/app/sanity.service.ts(21,14): error TS2339: Property 'fetch' does not exist on type 'object'.

Вот компонент, в который я внедряю сервис:

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Query } from '@angular/core/src/metadata/di';
import { SanityService } from '../sanity.service';

@Component({
    selector: 'app-product',
    templateUrl: './products.component.html',
    styleUrls: ['./products.component.css']
})
export class ProductsComponent implements OnInit {

    products: object[];

    constructor(private http: HttpClient, private sanityService: SanityService) { }

    ngOnInit() {

        this.sanityService.getProducts((res) => {
            this.products = res;
        });

    }

}

вот сервисный код (sanity.service.ts):

import { Injectable } from '@angular/core';
//const sanityClient = require('@sanity/client');
import * as SanityClient from '@sanity/client';

@Injectable()
export class SanityService {

    sanityClient: object;

    constructor() {
        this.sanityClient = SanityClient({
            projectId: 'someidhere',
            dataset: 'somedatabase',
            useCdn: true
        });
    }

    getProducts(callback) {
        let query = "*[_type == 'product']{ name, _id, description, price, 'imageUrl': image.asset->url }";
        this.sanityClient
            .fetch(
                query, // Query
                {} // Params (optional)
            ).then(res => {
                //console.log('5 movies: ', res)
                //this.products = res;
                callback(res);
            }).catch(err => {
                console.error('Oh no, error occured: ', err)
            });
    }



    getProductById(id, callback) {
        var query = `*[_id == '${id}']{ name, _id, description, price, 'imageUrl': image.asset->url }`;
        this.sanityClient
            .fetch(
                query, // Query
                {} // Params (optional)
            ).then(res => {
                //console.log('PRODUCT: ', res)
                //this.products = res;
                callback(res);
            }).catch(err => {
                console.error('Oh no, error occured: ', err)
            });
    }

}

Я подозреваю, что объект, создаваемый/устанавливаемый в конструкторе службы, еще не завершил «загрузку», когда вызывается функция «getProducts()», и, следовательно, свойство «fetch» ​​не существует. ошибка.

Я действительно в тупике здесь... может кто-нибудь помочь мне?

Также вот мой app.component.ts на всякий случай:

import { Component } from '@angular/core';
import { SanityService } from './sanity.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  providers: [SanityService]
})
export class AppComponent {
  title = 'app';

  constructor(private sanityService: SanityService) {}
}

person Pippy Longstocking    schedule 22.03.2018    source источник
comment
Не вводите свои переменные как «простой объект», потому что тогда компилятор машинописного текста будет рассматривать его как пустой объект без каких-либо свойств или методов в нем... вы получите ошибку времени компиляции, когда попытаетесь получить доступ к любому свойству объекта с помощью оператора точки (Object.propertyName), однако нотация массива (Object[propertyName]) будет работать нормально.   -  person Nikx Fabrizio    schedule 22.03.2018
comment
@NikxFabrizio спасибо за вклад ... однако вы не упомянули, как объявить переменную .... кажется, что «любой» будет работать.   -  person Pippy Longstocking    schedule 23.03.2018


Ответы (2)


Попробуйте ввести SanityClient как any или, если у вас есть включенные типы, как SanityClient. Ввод в качестве объекта указывает TypeScript рассматривать его как простой объект без каких-либо дополнительных функций, поэтому выдается эта ошибка!

Таким образом, изменение sanityClient: object на sanityClient: any должно позволить вашему приложению скомпилироваться.

person OClyde    schedule 22.03.2018

Вы можете создать интерфейс или модель класса, которая содержит метод fetch.

С интерфейсом:

export interface Fetch {
    fetch
}

Или с моделью:

export class Fetch {
   fetch
}

Итак, после создания модели класса, например, импортируйте ее и сделайте следующее:

sanityClient: Fetch;

разницу между ними можно найти здесь.

Рассмотрите возможность использования класса вместо интерфейса для сервисов и объявляемых объектов (компонентов, директив и каналов).

Рассмотрите возможность использования интерфейса для моделей данных.

person Radonirina Maminiaina    schedule 22.03.2018
comment
Почему бы просто не объявить переменную как «любую», как правильно предложил Oclyde выше? какая-то причина, по которой вы должны делать это вместо более простого объявления? Спасибо. - person Pippy Longstocking; 23.03.2018
comment
Да, вы правы, но если вам нужен другой тип объекта. - person Radonirina Maminiaina; 23.03.2018