Ошибка: FourSquareService.getVenues не является функцией

AngularJs – как использовать factory с вводом формы как часть URL-адреса для извлечения?

Первый вопрос здесь. Я изучаю angular и пытаюсь использовать отдельные файлы для своих сервисов, а также использую пользовательский ввод в форме как часть URL-адреса запроса. Я заставил его работать, внедрив $http в свой контроллер и вызвав службу внутри функции по щелчку, но чтобы все было чисто, я действительно хочу хранить службы в отдельных файлах и вызывать их внутри моего контроллера. Я попытался вернуть функцию с одним атрибутом в своей службе, чтобы я мог анализировать ввод (ng-model = cityInput) при ее вызове. Но когда я вызываю его на своем контроллере (после добавления службы в качестве зависимости), он дает мне FourSquareService.getVenues не является ошибкой функции. Что я делаю не так? Заранее спасибо. Код ниже:

служба Foursquare

 // Foursquare API Info
    const clientId = 'PU3IY1PZEOOANTPSHKNMS5HFSMEGEQ1IAVJYGYM4YVZP3NGD';
    const clientSecret = '0V21IXU0EETE3SZJGGCP4T4R13NUTBJ0LMI5WQY45IMDPEKY';
    const url = 'https://api.foursquare.com/v2/venues/explore?near=';
    const imgPrefix = 'https://igx.4sqi.net/img/general/150x200';
    
    // Current day
    function getCurrentDate() {
        let today = new Date();
        let yyyy = today.getFullYear();
        let mm = today.getMonth() + 1;
        let dd = today.getDate();
        if (dd < 10) {
            dd = '0' + dd
        }
        if (mm < 10) {
            mm = '0' + mm
        }
        return yyyy + mm + dd;
    };
    let currentDay = getCurrentDate();
    
    //Foursquare Angular request
    app.factory('fourSquareService', ['$http', function ($http) {
        return {
            getVenues: function(place) {
            const fourSquareURL = `${url}${place}&venuePhotos=1&limit=5&client_id=${clientId}&client_secret=${clientSecret}&v=${currentDay}`;
            return $http.get(fourSquareURL);
        }
    }
    }]);

Служба APIXU

// APIXU Info
const apiKey = '44972f525fb14478ac0224821182604';
const forecastUrl = 'https://api.apixu.com/v1/forecast.json?key=';

//Angular request
app.factory('apixuService', ['$http', function ($http) {
    return {
        getForecast: function (place) {
            const apixuURL = `${forecastUrl}${apiKey}&q=${place}&days=4&hour=10`;
            return $http.get(apixuURL);
        },
        getCurrentWeather: function (place) {
            const currentWeatherUrl = `${forecastUrl}${apiKey}&q=${place}`;
            return $http.get(currentWeatherUrl);
        }
    };
}]);

Контроллер

app.controller('MainController', ['$scope', 'apixuService', 'fourSquareService', function ($scope, fourSquareService, apixuService) {
    //Search on Click Function
    $scope.executeSearch = function () {

        //Venues
        fourSquareService.getVenues($scope.cityInput).then(function (response) {
            $scope.fouSquareData = response.data.response
            $scope.destination = $scope.fouSquareData.geocode.displayString;
            $scope.venues = $scope.fouSquareData.groups[0].items.map(spot => spot.venue);
            let photos = [];
            $scope.venues.forEach((venue, index) => venue.photos.groups[0] && venue.url ? photos.push(`<a href="${venue.url}" target="_blank"><img class="venueimg" src="${imgPrefix}${venue.photos.groups[0].items[0].suffix}"/></a>`) : venue.photos.groups[0] ? photos.push(`<img class="venueimg" src="${imgPrefix}${venue.photos.groups[0].items[0].suffix}"/>`) : photos.push('<img class="venueimg" src="./img/320px-No_image_available.png"/>'));
            $scope.photos = photos;
        }, function (error) {
            $scope.showdestination = true;
            $scope.showData = false;
            $scope.destination = 'Place not found, please try again.';
        });

        //Current Weather
        getWeather.getCurrentWeather($scope.cityInput).then(function (response) {
            $scope.currentWeather = response.data.current;
            $scope.place = response.data.location.name;
        });

        //Forecast
        getWeather.getForecast($scope.cityInput).then(function (response) {
            $scope.showdestination = true;
            $scope.showData = true;
            $scope.forecast = response.data.forecast.forecastday;
            const weekDays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
            $scope.weekDays = [];
            $scope.forecast.forEach(function (day, index) {
                $scope.weekDays[index] = weekDays[(new Date(day.date)).getDay()]
            });
            $scope.weekDays[0] = 'Today';
            $scope.weekDays[1] = 'Tomorrow';
        });

    };

}]);

person Pedro Santos    schedule 28.05.2018    source источник
comment
Возможный дубликат Как работает неявная/inline/$inject зависимость работа с инъекциями в AngularJS?.   -  person georgeawg    schedule 28.05.2018
comment
Этой проблемы с внедрением зависимостей можно избежать, используя неявную аннотацию. Такие инструменты, как ng-annotate, позволяют использовать неявные аннотации зависимостей в приложении и автоматически добавлять встроенные аннотации массива. до минификации.   -  person georgeawg    schedule 28.05.2018


Ответы (2)


У вас есть несоответствие при ссылке на ваши зависимости

Это должно быть это

app.controller('MainController', ['$scope', 'apixuService', 'fourSquareService', 
function ($scope, apixuService, fourSquareService) {
        //Search on Click Function
        $scope.executeSearch = function () {

        //Venues
        fourSquareService.getVenues($scope.cityInput).then(function (response) {
            $scope.fouSquareData = response.data.response
            $scope.destination = $scope.fouSquareData.geocode.displayString;
            $scope.venues = $scope.fouSquareData.groups[0].items.map(spot => spot.venue);
            let photos = [];
            $scope.venues.forEach((venue, index) => venue.photos.groups[0] && venue.url ? photos.push(`<a href="${venue.url}" target="_blank"><img class="venueimg" src="${imgPrefix}${venue.photos.groups[0].items[0].suffix}"/></a>`) : venue.photos.groups[0] ? photos.push(`<img class="venueimg" src="${imgPrefix}${venue.photos.groups[0].items[0].suffix}"/>`) : photos.push('<img class="venueimg" src="./img/320px-No_image_available.png"/>'));
            $scope.photos = photos;
        }, function (error) {
            $scope.showdestination = true;
            $scope.showData = false;
            $scope.destination = 'Place not found, please try again.';
        });

        //Current Weather
        apixuService.getCurrentWeather($scope.cityInput).then(function (response) {
            $scope.currentWeather = response.data.current;
            $scope.place = response.data.location.name;
        });

        //Forecast
        apixuService.getForecast($scope.cityInput).then(function (response) {
            $scope.showdestination = true;
            $scope.showData = true;
            $scope.forecast = response.data.forecast.forecastday;
            const weekDays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
            $scope.weekDays = [];
            $scope.forecast.forEach(function (day, index) {
                $scope.weekDays[index] = weekDays[(new Date(day.date)).getDay()]
            });
            $scope.weekDays[0] = 'Today';
            $scope.weekDays[1] = 'Tomorrow';
        });

    };

}]);
person John Velasquez    schedule 28.05.2018
comment
О, я забыл изменить это, прежде чем вставить сюда. Спасибо. Этот контроллер основан на старых именах, которые я использовал. Во всяком случае, это дает мне ту же ошибку, что и FourSquareService.getVenues не является функцией - person Pedro Santos; 28.05.2018
comment
все еще ваш отредактированный пост имеет несоответствие, вы пробовали это? - person John Velasquez; 28.05.2018
comment
Я немного заблудился в своих редакциях, и теперь он работает после того, как я изменил порядок внутри параметров функции, чтобы он соответствовал тому же порядку в зависимостях службы. Этот порядок важен? Не знал, что - person Pedro Santos; 28.05.2018
comment
Да, это важно. - person John Velasquez; 28.05.2018
comment
Не знал этого до сих пор. Большое спасибо =) - person Pedro Santos; 28.05.2018
comment
Рад помочь :) - person John Velasquez; 28.05.2018

Я изменил порядок параметров внутри функции контроллера, чтобы он соответствовал порядку зависимостей, и это сработало! Не знал, что порядок важен.

рабочий контроллер:

 app.controller('MainController', ['$scope', 'fourSquareService', 'apixuService', 
function ($scope, fourSquareService, apixuService) {
        //Search on Click Function
        $scope.executeSearch = function () {

            //Venues
            fourSquareService.getVenues($scope.cityInput).then(function (response) {
                $scope.fouSquareData = response.data.response
                $scope.destination = $scope.fouSquareData.geocode.displayString;
                $scope.venues = $scope.fouSquareData.groups[0].items.map(spot => spot.venue);
                let photos = [];
                $scope.venues.forEach((venue, index) => venue.photos.groups[0] && venue.url ? photos.push(`<a href="${venue.url}" target="_blank"><img class="venueimg" src="${imgPrefix}${venue.photos.groups[0].items[0].suffix}"/></a>`) : venue.photos.groups[0] ? photos.push(`<img class="venueimg" src="${imgPrefix}${venue.photos.groups[0].items[0].suffix}"/>`) : photos.push('<img class="venueimg" src="./img/320px-No_image_available.png"/>'));
                $scope.photos = photos;
            }, function (error) {
                $scope.showdestination = true;
                $scope.showData = false;
                $scope.destination = 'Place not found, please try again.';
            });

            //Current Weather
            apixuService.getCurrentWeather($scope.cityInput).then(function (response) {
                $scope.currentWeather = response.data.current;
                $scope.place = response.data.location.name;
            });

            //Forecast
            apixuService.getForecast($scope.cityInput).then(function (response) {
                $scope.showdestination = true;
                $scope.showData = true;
                $scope.forecast = response.data.forecast.forecastday;
                const weekDays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
                $scope.weekDays = [];
                $scope.forecast.forEach(function (day, index) {
                    $scope.weekDays[index] = weekDays[(new Date(day.date)).getDay()]
                });
                $scope.weekDays[0] = 'Today';
                $scope.weekDays[1] = 'Tomorrow';
            });

        };

    }]);
person Pedro Santos    schedule 28.05.2018
comment
Этой проблемы с внедрением зависимостей можно избежать, используя неявную аннотацию. Такие инструменты, как ng-annotate, позволяют использовать неявные аннотации зависимостей в приложении и автоматически добавлять встроенные аннотации массива. до минификации. - person georgeawg; 28.05.2018