how to redirect using ng-click
Asked Answered
E

4

11

Super-simple AngularJS app I'm trying to build, to accept credentials into two text boxes, then use two-way binding to redirect on a button click to a url which includes the two variables in it.

My problem is, I can get it working for a simple

<a href=...>

(or maybe ng-href=...) but for some reason, no matter what I do, I can't get a redirect using a

<button>

I've tried a lot of variations, but here's what I'm trying to do

<button ng-click="$location.path('http://example.com/login.jsp?un={{username}}&pw={{password}}')" class="btn btn-lg btn-warning">Log In!</button>

I CAN get it working if I call a function in a controller, but this is such a simple thing, I'd like to get it done on the page if possible.

Also, as a side-question, what are the security concerns of logging into a site like this?

** Edit: The part that confuses me is, this works (just without two-way binding working):

<button onClick="window.open('http://www.example.com/{{username}}');">

I'd expect that changing onClick to ng-click would give me the same behaviour, but with two-way binding.

**Re-Edit / Solution Alright, so I finally got a workable solution.

I have NO idea why the Button tag won't work to give this behaviour, as stated above, but here's the working code.

<a href="https://www.example.com/login.jsp?un={{username}}&pw={{password}}" class="btn btn-lg btn-warning">Log In!</a>

By giving it the same class as I intended to use for the button, the text shows up looking like a button, just the same.

Embrace answered 24/7, 2014 at 17:33 Comment(5)
You can't get it to work, because $location isn't in the scope, so it's not accessible in your view.Petrochemistry
Is it possible with any other variation of window or location? It's odd, because I can get a redirect using normal javascript using onClick, but that doesn't give me my two-way binding. So changing it to ng-click I'd expect it to act the same, but with two-way binding, but then it doesn't do anything.Embrace
"I'd like to get it done on the page if possible." This would simply be bad design. Use a function in your controller!Stagg
Yes, and you should only have a single space after a period. But when I put two spaces, it doesn't really matter, unless I'm applying to a position which would care. Likewise, I understand that 'best practices' would make what should be a single-page, no-controller AngularJS example into a multi-file, multi-folder setup, with everything encapsulated within generic functions, etc. What I'm trying to get at is, why does onClick and ng-click act different in this case? Two-way binding works without a controller, and window.open works without angular, why don't the two work together?Embrace
You should disable the link until the {{username}} and {{password}} are set, and when doing dyanmic urls like this is good practice to use ng-href (docs.angularjs.org/api/ng/directive/ngHref) although it may not matter in this case because it appears to depend on user input so it wont help you (i.e. you need enable/disable).Hemoglobin
H
15

Put a method on your controller to do the redirect and have that called form the ng-click on your button.

Markup:

<button ng-click="goLogin()">Log in</button>

Controller:

.controller('LoginCtrl', function($scope, $location) {
    $scope.form = {
        username: null,
        password: null
    };

    $scope.goLogin = function() {
        $location.url('http://test.com/login.jsp?un='+ $scope.form.username +'&pw="+ $scope.form.password);
    };
})

Also note you want to call $location.url() not path()

OR...

Add $location to your scope and call url({{newUrl}}):

$controller('MyCtrl', function($scope, $location) {
    $scope.$location = $location;
})

I'd still go with calling method on the scope.

Hemoglobin answered 24/7, 2014 at 18:11 Comment(2)
I think OP knows that: "I CAN get it working if I call a function in a controller"Petrochemistry
cant we directly do ng-click="$location.path('/edit')" ? and inject $location service in the controller so that location service will be accessible in the view/ partialsPhotoactinic
C
11

Few things to note here:

  1. Referencing the Window in Angular expressions is disallowed!, so trying to use $window.location.href = '/url' on an inline ng-click expression will not work.
  2. $location is not exposed automatically to your scope, you'll need to expose this to the view by injecting it first to the controller and then the scope.

    .controller('LoginCtrl', function($scope, $location) { $scope.$loc = $location; })

  3. It's worth noting that $location.path() & $location.url() will NOT redirect you to a new page, this is used for routing so that route callbacks/watchers can do it's thing. The $location service allows you to change only the URL; it does not allow you to reload the page.

  4. The best (and also angular way imo) is to add a method to your scope in the controller. When you need to change the URL and reload the page or navigate to a different page, please use a lower level API: $window.location.href.

Use a method bound to your controller:

$scope.redirect = function(url, refresh) {
    if(refresh || $scope.$$phase) {
        $window.location.href = url;
    } else {
        $location.path(url);
        $scope.$apply();
    }
}

And then call your method from your ng-click expression:

<button ng-click="redirect('/')">GO HOME! NO BODY LOVES YOU</button>

Note: The above method will require you to inject both $location & $window to your controller.

Cinder answered 26/7, 2015 at 22:45 Comment(0)
O
6

you can also use ng-href.

<button ng-href="http://example.com/login.jsp?un={{username}}&pw={{password}}" class="btn btn-lg btn-warning">Log In!</button>
Ornamentation answered 21/9, 2015 at 23:18 Comment(1)
How did you get this to work when href doesn't work with button elements?Medwin
S
0

This should definitely work

$scope.loadSchedules = function () {

        window.location.href = '/Admin/Admin/DoctorsSchedule';
        
    };


**Define a function inside "ng-click" attribute**
<button type="button" class="btn btn-primary success" ng-click="loadSchedules()">Ok</button>
Shortchange answered 3/4, 2021 at 10:23 Comment(1)
The questioner mentions this 'I CAN get it working if I call a function in a controller'. He is looking for other approachesIsis

© 2022 - 2024 — McMap. All rights reserved.