1

I am new to angular and what I am willing to do is replace a piece of code I wrote in the past in jquery to angularjs.

The goal is to take a string from a span element, split it in two and pass the two strings as parameters in a GET request.

I am trying to learn best coding pratices and improving myself so any comments of any kind are always welcome.

Working Code in jquery:

//Get Song and Artists  

setInterval(function () {
var data = $('#songPlaying').text();
var arr = data.split('-');

var artist = arr[0];
var songTitle = arr[1];

//Request Lyrics

$.get('lyricsRequester.php', { "song_author": artist, "song_name" : songTitle}, 
function(returnedData){
     console.log(returnedData);
    $('#refreshLyrics').html(returnedData);
});
},10000); 

Code in Angular

    var app = angular.module("myApp", []);


app.factory('lyricService', function($http) {
   return {
        getLyrics: function($scope) {
        //$scope.songArr = $scope.currentSong.split('-'); <-- **undefined currentSong**
        //$scope.artist = $scope.songArr[0];
        //$scope.songTitle = $scope.songArr[1];
             return 
             $http.get('/lyricsRequester.php', {
        params: {
            song_author: $scope.artist,
            song_name: $scope.songTitle
        }
     }).then(function(result) {
            return result.data;
                        });
        }
   }
});

app.controller('lyricsController', function($scope, lyricService, $interval) {
   $interval(function(){ 

        lyricService.getLyrics().then(function(lyrics) {
            $scope.lyrics = lyrics; <-- **TypeError: Cannot read property 'then' of undefined**
            console.log($scope.lyrics);
        }); 

        }, 10000);
});

index.html (just a part)

<div class="col-md-4" ng-controller="lyricsController">{{lyrics}}</div>
    <div class="col-md-4"><h3><span id="currentSong" ng-model="currentSong"></span></h3><div>
1

2 Answers 2

1

You need to be careful with your return statement when used in conjunction with newlines, in these lines:

return 
$http.get('/lyricsRequester.php', 

If you don't, JS will automatically add a semicolon after your return, and the function will return undefined.

Move the $http.get statement to the same line as your return statement.

return $http.get('/lyricsRequester.php', ...

Refer to the following docs:

MDN return statement

Automatic Semicolon Insertion


As for your second issue, you $scope is not really something you inject into your services (like $http). Scopes are available for use in controllers. You need to refactor your code a bit to make things work.

eg. Your getLyrics function can take a song as a parameter. Then in your controller, you call lyricsService.getLyrics(someSong). Scope access and manipulation are only done in your controller.

app.factory('lyricService', function($http) {
   return {
        getLyrics: function(song) {
        var songArr = song.split('-');
        var artist = songArr[0];
        var songTitle = songArr[1];
        return $http.get('/lyricsRequester.php', {
          params: {
              song_author: artist,
              song_name: songTitle
          }
     }).then(function(result) {
            return result.data;
                        });
        }
   }
});
app.controller('lyricsController', function($scope, lyricService) {
    $scope.currentSong = 'Judas Priest - A Touch of Evil';

   $interval(function(){ 
        lyricService.getLyrics($scope.currentSong).then(function(lyrics) {
            $scope.lyrics = lyrics;
            console.log($scope.lyrics);
        }); 

        }, 10000);
});

You also have some other issues, like using ng-model on your span. ng-model is an angular directive that is used in conjunction with form elements (input, select etc.), not a span as you have. So you might want to change that into an input field.

Sign up to request clarification or add additional context in comments.

4 Comments

thank you! that seems to solve one of the two problems of mine! I see the undefind currentSong only now.
You're trying to inject and access $scope in your service. $scope can only be injected into controllers.
ah that's true, i passed it from the controller and the request is visible through the console now. Many thanks to all of you :)
I still need it on a span but i managed to do it with jquery text() temporary until I find an other way to pass it. Works great anyways. Thanks :)
1

$http does not use .then, it uses .success and .error. the line that you have where it says then is undefined, should be replaced with a success and error handler instead. Below is a sample from the docs:

// Simple GET request example :
$http.get('/someUrl').
  success(function(data, status, headers, config) {
    // this callback will be called asynchronously
    // when the response is available
  }).
  error(function(data, status, headers, config) {
    // called asynchronously if an error occurs
    // or server returns response with an error status.
  });

See Link: https://docs.angularjs.org/api/ng/service/$http

1 Comment

thanks but the TypeError: Cannot read property 'then' of undefined persists in the controller. If I uncomment $scope.songArr = $scope.currentSong.split('-'); I get undefind currentSong

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.