1

I'm very new to Angular JS and am running into a slight snag. I'm sure this is probably easy to answer but my research so far has been unsuccessful.

I'm using Visual Studio as my IDE and have followed the tutorial here to start a project using AngularJS.

The initial output of the tutorial works great. What I'm trying to do now is add in support for reading a parameter from the url. Something like index.html?target=bob

I found this answer which shows the general methods for using $location to grab the paramters from the url and display the results on the page.

I am having issues applying this logic to my current structure. I assume it's something basic that I've missed so far so apologies if this question is too simplistic.

Here's my current code.

index.html

<!DOCTYPE html>

<html ng-app="app">
<head>
    <title></title>
</head>
<body ng-controller="Main as vm">

    <input type="text" ng-model="vm.food" placeholder="Enter food" />

    <p>Sriracha sauce is great with {{vm.food}}!</p>

    Target: {{vm.test}}<br />

    <script src="Scripts/angular.min.js"></script>
    <script src="app/app.module.js"></script>
    <script src="app/main.js"></script>

</body>
</html>

app.module.js

(function () {
    'use strict';

    angular.module('app', [], function ($locationProvider) {
        $locationProvider.html5Mode(true);
    });

})();

main.js

(function () {
    'use strict';

    angular
        .module('app')
        .controller('Main', main($location));

    function main($location) {
        var vm = this;
        vm.food = 'pizza';
        vm.test = $location.search()['target']
    }

})();

The page renders as such:

Output

I am getting the following errors in the console which seem obvious but I'm at a loss as to what my next step should be. Error

Clearly the issue lies in main not understanding $location. But why? What do?!

Thanks!

SOLVED

Both Claise and squiroid provided excellent answers to this below. Since squiroid's solution is what I'm currently using I'll accept that answer but Claise's answer provides a bit more in depth information on this issue for future reference.

I'd like to note also that the second error listed above was solved by adding <base href="/"> to the head section of index.html

Thanks everyone!

4
  • I'm not really sure about that controller function implementation. You might want to pass the $location service with [] if you are applying any automated minification. Commented Jan 5, 2017 at 17:40
  • 1
    See the official guide examples how they are passing $scope: docs.angularjs.org/guide/controller Commented Jan 5, 2017 at 17:41
  • Your error is regarding Main being undefined. If you want to keep the code as you have it, I would try moving Main function declaration above the line of code where its called. Commented Jan 5, 2017 at 17:49
  • @Joshua please check my answer :) Commented Jan 5, 2017 at 17:55

3 Answers 3

2

You are using a derivative style of angular declarations here, which allows you to declare all the controllers in a single block, with all the functions following, rather than the traditional inline method. This works, but you have made a few errors in your use of this form.

First, the .controller('Main', main($location)); line is incorrect. the function .controller() is accepting the name of the function as an argument, it is not calling the function. Therefore, the (), and the list of arguments is unnecessary. controller('Main', main); is what is expected here.

Moving to your function declaration next, function main($location) {...} will work, as long as your code is not minified. As soon as you minify your code, angular will no longer be able to identify which dependency $location represents, and the code will break.

Again, you can refer to inline injections, where you use

.controller('Main',['$inject', main]);

but you also have an option to provide another separation of the dependencies from the declarations.

Angular provides an alternative method, $inject. You can assign an array to the $inject property of your function, to provide the correct dependencies. main.$inject = ['$location'];.

In summary, here is the corrected main.js file:

(function () {
'use strict';

angular
    .module('app')
    .controller('Main', main);

function main($location) {
    var vm = this;
    vm.food = 'pizza';
    vm.test = $location.search()['target']
}

main.$inject = ['$location'];
})();

And a Plunker showing the changes: http://plnkr.co/edit/j9FnhiFPjkSrY5muhb0J?p=preview

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

Comments

1

Here is the working plunker for you.

https://plnkr.co/edit/GUDPceYFLNldiqd94vZ1?p=preview

Some code needs to be changed in controller.

(function () {
    'use strict';

    angular
        .module('app')
        .controller('Main', ['$location', main]);

    function main($location) {
        var vm = this;
        vm.food = 'pizza';
        vm.test = $location.search()['target']
    }

})();

There were two problems:

  1. Problem with you code is that you have called the main method instead of passing it as callback function

  2. You haven't passed the $location from controller to the callback method.

    ['$location', main]

EDIT: Updated the plunker and give the appropriate answer.

1 Comment

Writing the detailed answer in few minutes.
-1
(function () {
    'use strict';
    angular.module('app', [])
     .config(function ($locationProvider) {
        $locationProvider.html5Mode(true);
     }));
})();

Try placing the locationProvider under config in your app.module.js as above. Also in your main.js, if 'target' is the key value of the parameter you can write vm.test = $location.search('target');

(function () {
  'use strict';

  angular
    .module('app')
    .controller('Main', function($location) {
       var vm = this;
       vm.food = 'pizza';
       vm.test = $location.search('target');
    })();

2 Comments

Do you mean the config part or the controller?
No, .controller('Main', main($location)); will probably throw a syntax error. You should create a state and test if it will or not. Probably will :)

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.