Struggling with AngularJs - How to Utilize Factory Alongside Form Input in URL for Data Fetching?
This is my first time asking a question here. I've been diving into Angular and wanted to organize my services by separating them into different files. Additionally, I aimed to incorporate user input from a form as part of the request URL. Although I managed to get it working by injecting $http into my controller and invoking the service within the click function, I prefer maintaining clean code by keeping services in separate files and calling them within the controller. I attempted to create a single attribute function in my service that could handle parsing the input (ng-model="cityInput") when invoked. However, upon calling it in my controller (after adding the service as a dependency), I encountered an error stating "fourSquareService.getVenues is not a function". What am I missing here? Appreciate any help. See code below:
Foursquare Service
// Foursquare API Details
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';
// Get Current Date
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 Service
// 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);
}
};
}]);
Controller
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
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';
});
};
}]);