When my app accesses an API, it retrieves an array of 'card' objects and showcases each one on the user interface.
The HTML file for card search is: card-search.html
<div class="main-view container">
<h1>Card Search</h1>
<div id="card-search" ng-controller="cardSearchController">
<form class="search-form">
<p>Retrieve card information via name or multiverse ID</p>
<input ng-model="cardInput" type="text" name="" value="">
<select ng-model="selectedItem" ng-options="item as item.label for item in items"></select>
<button ng-click="getCard(cardInput)" type="button" name="button">Search</button>
</form>
<div class="container result-container">
<div ng-repeat="card in displayedCards" class="row display-row">
<div class="col-sm-6 card-display">
<img src={{card.imageUrl}} alt="">
</div>
<div class="col-sm-6 card-stat-display">
<p><strong>Name:</strong> {{card.name}}</p>
<p><strong>Mana Cost:</strong> {{card.manaCost}}</p>
<p><strong>Converted Mana Cost:</strong> {{card.cmc}}</p>
<p><strong>Colors:</strong> {{card.colors}}</p>
<p><strong>Type:</strong> {{card.type}}</p>
<p><strong>Text:</strong> {{card.text}}</p>
<p><strong>Flavor Text:</strong> <i> {{card.flavor}}</i></p>
<p><strong>power:</strong> {{card.power}}</p>
<p><strong>Toughness:</strong> {{card.toughness}}</p>
</div>
</div>
</div>
</div>
The intention here is to showcase every card in cardDisplay
, which is a collection of objects.
The controller responsible for this functionality is located at cardSearchController.js
angular.module('mainApp').controller('cardSearchController', function($scope, mainService) {
$scope.getCard = function(searchInput) {
console.log('$scope.selectedItem.label', $scope.selectedItem.label)
if ($scope.selectedItem.label === 'Search By Multiverse ID') {
mainService.getCardById(searchInput).then(function(card){
$scope.displayedCard = card;
})
}
if ($scope.selectedItem.label === 'Search By Name') {
var searchInput = searchInput.split(' ').join('+')
mainService.getCardByName(searchInput).then(function(uniqueCards){
console.log('unique cards in controller', uniqueCards);
$scope.displayedCards = uniqueCards;
})
}
};
$scope.items = [
{
label: 'Search By Name'
},
{
label: 'Search By Multiverse ID'
}
]
});
This script defines the logic that should pass back uniqueCards
.
The service related to this operation can be found in service.js:
angular.module('mainApp').service('mainService', function($http,
$state) {
this.getCardByName = function(name) {
console.log(11111, 'I am here');
return $http({
method: 'GET',
url: 'https://api.magicthegathering.io/v1/cards?name=' + name + '&contains=imageUrl'
}).then(function(response) {
console.log(response.data);
var returnedCards = response.data.cards;
var uniqueCards = [];
console.log('the contents of returned cards: ', returnedCards);
for (var card of returnedCards) {
var testedCard = card;
var uniqueName = true;
for (var uniqueCard of uniqueCards) {
if (testedCard.name === uniqueCard.name) {
uniqueName = false;
break;
}
}
if (uniqueName) {
uniqueCards.push(testedCard);
}
}
console.log('here are the unique cards: ', uniqueCards);
return uniqueCards;
}),
function (cards) {
alert('An Error', cards);
};
}
This service sets up the retrieval process where this.getCardByName
aims to provide uniqueCards
back to the controller.
Despite successful creation of uniqueCards according to our logs, the controller doesn't seem to be receiving it. Moreover, the development console indicates an issue with invoking mainService.getCardByName
:
angular.js:14642 TypeError: mainService.getCardByName(...).then is not a function
at ChildScope.$scope.getCard (cardSearchController.js:14)
at fn (eval at compile (angular.js:15500), <anonymous>:4:223)
at callback (angular.js:27285)
at ChildScope.$eval (angular.js:18372)
at ChildScope.$apply (angular.js:18472)
at HTMLButtonElement.<anonymous> (angular.js:27290)
at HTMLButtonElement.dispatch (jquery-3.2.1.min.js:3)
at HTMLButtonElement.q.handle (jquery-3.2.1.min.js:3)
It seems that calling getCardByName
suggests it's undefined, even when the corresponding script tag exists within index.html.