Angular js factory ничего не возвращает с ошибкой 404

0

Я создаю небольшой проект, который позволяет пользователю вести список исполнителей и альбомов, и мне нужен был тип/автозаполнение, которое соответствовало бы таким вещам. Я черпал вдохновение из последнего.

Мой HTML-код:

<!DOCTYPE html>
<html class="js flexbox flexboxlegacy canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths ng-scope" ng-app="ymusica"><!--<![endif]--><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <title>ymusica</title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width">

        <link rel="stylesheet" href="lib/css/bootstrap.css">
        <link rel="stylesheet" href="lib/css/main.css">
        <script src="lib/js/modernizr.js"></script>
    <style type="text/css">@charset "UTF-8";[ng\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak{display:none;}ng\:form{display:block;}</style></head>
    <body>
        <!--[if lt IE 7]>
            <p class="chromeframe">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> or <a href="http://www.google.com/chromeframe/?redirect=true">activate Google Chrome Frame</a> to improve your experience.</p>
        <![endif]-->

        <div class="container">
             <div ng-controller="AlbumSearch" class="album-search text-center" ng-cloak>
                 <typeahead class="typeahead" items="music" term="term" search="searchMusic(term)" select="selectMusic(item)">
                     <div class="menu" ng-cloak>
                         <h3 ng-show="hasAlbums()">Albums</h3>
                         <ul>
                             <li typeahead-item="album" ng-repeat="album in albums" class="results">
                                 <img ng-src="{{imageSource(album)}}"><p class="name">{{album.name}}</p><p class="artist">{{album.artist}}</p>
                             </li>
                         </ul>
                         <h3 ng-show="hasArtists()">Artists</h3>
                         <ul>
                             <li typeahead-item="artist" ng-repeat="artist in artists" class="results">
                                 <img ng-src="{{imageSource(artist)}}"><p class="name">{{artist.name}}</p>
                             </li>
                         </ul>
                     </div>
                 </typeahead>
             </div>
         </div>

        <script src="lib/js/jquery.js"></script>
        <script src="lib/js/rx.js"></script>
        <script src="lib/js/rx.time.js"></script>
        <script src="lib/js/rx.coincidence.js"></script>
        <script src="lib/js/angular.js"></script>
        <script src="lib/js/module.js"></script>
        <script src="lib/js/ymusica.js"></script>
        <script src="lib/js/controller.js"></script>
        <script src="lib/js/service.js"></script>
        <script src="lib/js/typeahead.js"></script>
        <script src="lib/js/angular-resource.js"></script>
        <script src="lib/js/bootstrap.js"></script>


      </body>
</html>

Мой код контроллера:

angular.module('ymusica').controller('AlbumSearch', ['$scope', 'Albums', 'Artists', '$q', function($scope, albums, artists, $q) {

$scope.albums = [];
$scope.artists = [];

var watchToObservable = function(scope, expression) {
    var observable = new Rx.Subject();

    scope.$watch(expression, observable.onNext.bind(observable));

    return observable;
}

var functionToObservable = function(scope, name) {

    var observable = new Rx.Subject();

    scope[name] = function(value) {
        observable.onNext(value);
    };

    return observable;
}

var terms = functionToObservable($scope, 'searchMusic');

terms.sample(250)
    .select(function(term) {
        var promise = $q.all([albums.query(term), artists.query(term)]);
        return Rx.promiseToObservable(promise)
    })
    .switchLatest()
    .select(function(promise) { return [promise[0].data.albums, promise[1].data.artists]; })
    .subscribe(function(result) {
        $scope.albums = result[0].slice(0, 5);
        $scope.artists = result[1].slice(0, 5);
        $scope.music = $scope.albums.concat($scope.artists);
    });

$scope.selectMusic = function(item) {
    console.log('music selected!', item);
    $scope.term = item.name;
};

$scope.imageSource = function(item) {
    return item.images['medium'];
};

$scope.hasAlbums = function() {
    return $scope.albums.length > 0;
};

$scope.hasArtists = function() {
    return $scope.artists.length > 0;
};

}]);

Мой код service.js:

angular.module('ymusica').factory('Albums', ['$http', function($http) {
return {
    query: function(term) {
        return $http.get('/api/album', { params: { q: term } });
    }
  };
}]);

angular.module('ymusica').factory('Artists', ['$http', function($http) {
return {
    query: function(term) {
        return $http.get('/api/artist', { params: { q:term } });
    }
  };
}]);

и наконец

Мой typeahead.js код (директива):

angular.module('ymusica').directive('typeahead', ["$timeout",  function($timeout) {
return {
    restrict: 'E',
    transclude: true,
    replace: true,
    template: '<div><form><input ng-model="term" ng-change="query()"  type="text" autocomplete="off" /></form><div ng-transclude></div></div>',
    scope: {
        search: "&",
        select: "&",
        items: "=",
        term: "="
    },
    controller: ["$scope", function($scope) {
        $scope.items = [];
        $scope.hide = false;

        this.activate = function(item) {
            $scope.active = item;
        };

        this.activateNextItem = function() {
            var index = $scope.items.indexOf($scope.active);
            this.activate($scope.items[(index + 1) % $scope.items.length]);
        };

        this.activatePreviousItem = function() {
            var index = $scope.items.indexOf($scope.active);
            this.activate($scope.items[index === 0 ? $scope.items.length - 1  : index - 1]);
        };

        this.isActive = function(item) {
            return $scope.active === item;
        };

        this.selectActive = function() {
            this.select($scope.active);
        };

        this.select = function(item) {
            $scope.hide = true;
            $scope.focused = true;
            $scope.select({item:item});
        };

        $scope.isVisible = function() {
            return !$scope.hide && ($scope.focused || $scope.mousedOver);
        };

        $scope.query = function() {
            $scope.hide = false;
            $scope.search({term:$scope.term});
        }
     }],

    link: function(scope, element, attrs, controller) {

        var $input = element.find('form > input');
        var $list = element.find('> div');

        $input.bind('focus', function() {
            scope.$apply(function() { scope.focused = true; });
        });

        $input.bind('blur', function() {
            scope.$apply(function() { scope.focused = false; });
        });

        $list.bind('mouseover', function() {
            scope.$apply(function() { scope.mousedOver = true; });
        });

        $list.bind('mouseleave', function() {
            scope.$apply(function() { scope.mousedOver = false; });
        });

        $input.bind('keyup', function(e) {
            if (e.keyCode === 9 || e.keyCode === 13) {
                scope.$apply(function() { controller.selectActive(); });
            }

            if (e.keyCode === 27) {
                scope.$apply(function() { scope.hide = true; });
            }
        });

        $input.bind('keydown', function(e) {
            if (e.keyCode === 9 || e.keyCode === 13 || e.keyCode === 27) {
                e.preventDefault();
            };

            if (e.keyCode === 40) {
                e.preventDefault();
                scope.$apply(function() { controller.activateNextItem(); });
            }

            if (e.keyCode === 38) {
                e.preventDefault();
                scope.$apply(function() { controller.activatePreviousItem();  });
            }
        });

        scope.$watch('items', function(items) {
            controller.activate(items.length ? items[0] : null);
        });

        scope.$watch('focused', function(focused) {
            if (focused) {
                $timeout(function() { $input.focus(); }, 0, false);
            }
        });

        scope.$watch('isVisible()', function(visible) {
            if (visible) {
                var pos = $input.position();
                var height = $input[0].offsetHeight;

                $list.css({
                    top: pos.top + height,
                    left: pos.left,
                    position: 'absolute',
                    display: 'block'
                });
            } else {
                $list.css('display', 'none');
            }
        });
    }
  };
 }]);

angular.module('ymusica').directive('typeaheadItem', function() {
return {
    require: '^typeahead',
    link: function(scope, element, attrs, controller) {

        var item = scope.$eval(attrs.typeaheadItem);

        scope.$watch(function() { return controller.isActive(item); }, function(active) {
            if (active) {
                element.addClass('active');
            } else {
                element.removeClass('active');
            }
        });

        element.bind('mouseenter', function(e) {
            scope.$apply(function() { controller.activate(item); });
        });

        element.bind('click', function(e) {
            scope.$apply(function() { controller.select(item); });
        });
    }
 };
});

Я также использую last.fm api. Пожалуйста, помогите мне решить проблему. В исходном коде last.fm работает нормально, но мой код возвращает ошибку 404, хотя используется один и тот же путь api.

1 ответ

0

Кажется, что вы пытаетесь получить URL /api/artist из своего собственного домена, а не из серверов Last.fm:

return $http.get('/api/artist', { params: { q:term } })
Я _think_ он должен читать: return $http.get('https://last.fm/api/artist', { params: { q:term }});

Документы говорят, что:

Корневой URL API находится по адресу http://ws.audioscrobbler.com/2.0/

Кроме того, я не вижу конечной точки для поиска /api/artist с параметром q, хотя у них есть конечные точки search.

  • 0
    теперь выдает эту ошибку: last.fm/api/album?q=ma net :: ERR_INSECURE_RESPONSE
  • 0
    @ Sumanta736 Обновил ответ.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню