mrb398
mrb398

Reputation: 1317

Hide button and show data, upon button click, in Angular

It probably goes without saying that I'm quite new to angular as I'm trying to accomplish a relatively simple task, and I've come here for some help

I'm recreating our company's password vault using angular.

Here is what I am trying to accomplish.

The page loads with a list of accounts. Most the information is visible except for the password. I have a button that when clicked, hides the button, queries the database, logs who queried password, and displays the password to the user. The passwords are clear text because they aren't passwords for client accounts or anything sensitive, it exists for our employees to reference how/where to login to various websites we use for day to day business.

My HTML looks as follows:

    <tr ng-repeat="account in resp.PasswordVaultAccounts">
        <td><a href="{{account.URL}}" target="_blank">{{account.Name}}</a></td>
        <td>{{account.Username}}</td>
        <td><button ng-click="showPassword(account.AccountId);" class="btn btn-primary">View</button><span></span></td>
        <td>{{account.Comments}}</td>
    </tr>

My scope controller looks as follows

$scope.showPassword = function (accountId) {
        passwordVaultData.getAccountPassword(accountId)
            .$promise
            .then(function (r) {
                   //success
            }, function (r) {
                  //fail
            });
    }

My showPassword() method works and returns the correct password, but I can't figure out how to hide the button and display the password.

Upvotes: 0

Views: 554

Answers (3)

Steve Mitcham
Steve Mitcham

Reputation: 5313

Using the ng-show and ng-hide directives against the password on the account object should suffice for modifying the UI

<tr ng-repeat="account in resp.PasswordVaultAccounts">
    <td><a href="{{account.URL}}" target="_blank">{{account.Name}}</a></td>
    <td>{{account.Username}}</td>
    <td>
      <button ng-hide="account.Password" ng-click="showPassword(account.AccountId);" class="btn btn-primary">View</button>
      <span ng-show="account.Password">{{account.Password}}</span>
    </td>
    <td>{{account.Comments}}</td>
</tr>

As for the promise resolution, you want the getAccountPassword to return a promise, I will make an assumption about it's content below

function getAccountPassword(account) {
   var deferred = $q.defer();
   $http.get('api/vault/' + account.AccountId).then(function(r) {
      deferred.resolve(r);
   }, function(r) {
      deferred.reject(r);
   });
   return deferred.promise;
}

$scope.showPassword = function (account) {
    getAccountPassword(account.AccountId).then(function(password) {
      account.Password = password;
    }, function(password) {
      account.Password = undefined; // some type of error handling here
    });
 }

Because the promise is executed in the context of an $http call, the digest cycle will run and the elements will be shown based on whether password is populated.

Upvotes: 1

sylwester
sylwester

Reputation: 16498

Please see demo below

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


angular.module('app').
controller('firstCtrl', function($scope) {

  $scope.resp = {
    PasswordVaultAccounts: [{
        AccountId: 1,
        URL: "bbc.co.uk",
        Username: "Jack",
        Comments: "White"
      }, {
        AccountId: 2,
        URL: "bbc.co.uk",
        Username: "Mike",
        Comments: "Green"
      }, {
        AccountId: 3,
        URL: "bbc.co.uk",
        Username: "Tim",
        Comments: "Red"
      }



    ]
  }

  $scope.showPassword = function(account) {
    //call you backend and on sucess add that :

    // passwordVaultData.getAccountPassword(account.accountId)
    //      .$promise
    //      .then(function (r) {
    account.showpass = true;
    account.pass = account.Username + " password is *****"

  }

});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<body ng-app="app">
  <div ng-controller="firstCtrl">

    <table>
      <tr ng-repeat="account in resp.PasswordVaultAccounts">
        <td><a href="{{account.URL}}" target="_blank">{{account.Name}}</a>
        </td>
        <td>{{account.Username}}</td>
        <td>
          <button ng-click="showPassword(account);" class="btn btn-primary" ng-hide="account.showpass">View</button>
          <span ng-show="account.showpass">{{account.pass}}</span>
        </td>
        <td>{{account.Comments}}</td>
      </tr>
    </table>
  </div>
</body>

Upvotes: 0

Karthik
Karthik

Reputation: 1377

You can accomplish it by either ng-if or ng-show/hide:

Quick sample below:

 <tr ng-repeat="account in resp.PasswordVaultAccounts">
    <td><a href="{{account.URL}}" target="_blank">{{account.Name}}</a></td>
    <td>{{account.Username}}</td>
    <td>
       <button ng-if="!account.password" ng-click="showPassword(account);" class="btn btn-primary">View</button><span></span></td>
       <span ng-if="account.password">{{password}}</span>
    <td>{{account.Comments}}</td>
</tr>


$scope.showPassword = function (account) {
    account.password = passwordVaultData.getAccountPassword(account.AccountId)
        .$promise
        .then(function (r) {
               //success
        }, function (r) {
              //fail
        });
}

Upvotes: 0

Related Questions