JavaScript and RxJS Password Strength Indicator

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
2
down vote

favorite












This is my first time using RxJS (or any observable library). It seems to work okay but I'm not sure about best practices.



The thing that I am most unsure about is subscribing to the observable multiple times. I couldn't decide if it would be better to subscribe to it once with one big function, or to use many smaller subscribers.



CodePen Demo



Markup



<div class="field">
<label class="label">Password</label>
<div class="control has-icons-left">
<input id="password" class="input" type="password" />
<span class="icon is-small is-left">
<i class="fa fa-lock"></i>
</span>
</div>
<p id="passwordHelp" class="help is-danger"></p>
</div>
<div class="field">
<label class="label">Password Strength</label>
<progress id="passwordStrength" class="progress is-danger" value="0" max="5" />
</div>


Script



const fromEvent = rxjs
const map, filter = rxjs.operators

document.addEventListener('DOMContentLoaded', () =>
const passwordInput = document.getElementById('password')
const passwordHelp = document.getElementById('passwordHelp')
const passwordStrength = document.getElementById('passwordStrength')

const passwordChanged$ = fromEvent(passwordInput, 'input')
.pipe(
map(x => x.target.value),
map(zxcvbn)
)

passwordChanged$
.pipe(map(password => password.score > 2 ? 'success' : 'danger'))
.subscribe(state =>
passwordInput.className = `input is-$state`
passwordStrength.className = `progress is-$state`
)

passwordChanged$
.subscribe(password => passwordHelp.innerHTML = password.feedback.warning )

passwordChanged$
.subscribe(password => passwordStrength.setAttribute('value', password.score + 1) )
)






share|improve this question



























    up vote
    2
    down vote

    favorite












    This is my first time using RxJS (or any observable library). It seems to work okay but I'm not sure about best practices.



    The thing that I am most unsure about is subscribing to the observable multiple times. I couldn't decide if it would be better to subscribe to it once with one big function, or to use many smaller subscribers.



    CodePen Demo



    Markup



    <div class="field">
    <label class="label">Password</label>
    <div class="control has-icons-left">
    <input id="password" class="input" type="password" />
    <span class="icon is-small is-left">
    <i class="fa fa-lock"></i>
    </span>
    </div>
    <p id="passwordHelp" class="help is-danger"></p>
    </div>
    <div class="field">
    <label class="label">Password Strength</label>
    <progress id="passwordStrength" class="progress is-danger" value="0" max="5" />
    </div>


    Script



    const fromEvent = rxjs
    const map, filter = rxjs.operators

    document.addEventListener('DOMContentLoaded', () =>
    const passwordInput = document.getElementById('password')
    const passwordHelp = document.getElementById('passwordHelp')
    const passwordStrength = document.getElementById('passwordStrength')

    const passwordChanged$ = fromEvent(passwordInput, 'input')
    .pipe(
    map(x => x.target.value),
    map(zxcvbn)
    )

    passwordChanged$
    .pipe(map(password => password.score > 2 ? 'success' : 'danger'))
    .subscribe(state =>
    passwordInput.className = `input is-$state`
    passwordStrength.className = `progress is-$state`
    )

    passwordChanged$
    .subscribe(password => passwordHelp.innerHTML = password.feedback.warning )

    passwordChanged$
    .subscribe(password => passwordStrength.setAttribute('value', password.score + 1) )
    )






    share|improve this question























      up vote
      2
      down vote

      favorite









      up vote
      2
      down vote

      favorite











      This is my first time using RxJS (or any observable library). It seems to work okay but I'm not sure about best practices.



      The thing that I am most unsure about is subscribing to the observable multiple times. I couldn't decide if it would be better to subscribe to it once with one big function, or to use many smaller subscribers.



      CodePen Demo



      Markup



      <div class="field">
      <label class="label">Password</label>
      <div class="control has-icons-left">
      <input id="password" class="input" type="password" />
      <span class="icon is-small is-left">
      <i class="fa fa-lock"></i>
      </span>
      </div>
      <p id="passwordHelp" class="help is-danger"></p>
      </div>
      <div class="field">
      <label class="label">Password Strength</label>
      <progress id="passwordStrength" class="progress is-danger" value="0" max="5" />
      </div>


      Script



      const fromEvent = rxjs
      const map, filter = rxjs.operators

      document.addEventListener('DOMContentLoaded', () =>
      const passwordInput = document.getElementById('password')
      const passwordHelp = document.getElementById('passwordHelp')
      const passwordStrength = document.getElementById('passwordStrength')

      const passwordChanged$ = fromEvent(passwordInput, 'input')
      .pipe(
      map(x => x.target.value),
      map(zxcvbn)
      )

      passwordChanged$
      .pipe(map(password => password.score > 2 ? 'success' : 'danger'))
      .subscribe(state =>
      passwordInput.className = `input is-$state`
      passwordStrength.className = `progress is-$state`
      )

      passwordChanged$
      .subscribe(password => passwordHelp.innerHTML = password.feedback.warning )

      passwordChanged$
      .subscribe(password => passwordStrength.setAttribute('value', password.score + 1) )
      )






      share|improve this question













      This is my first time using RxJS (or any observable library). It seems to work okay but I'm not sure about best practices.



      The thing that I am most unsure about is subscribing to the observable multiple times. I couldn't decide if it would be better to subscribe to it once with one big function, or to use many smaller subscribers.



      CodePen Demo



      Markup



      <div class="field">
      <label class="label">Password</label>
      <div class="control has-icons-left">
      <input id="password" class="input" type="password" />
      <span class="icon is-small is-left">
      <i class="fa fa-lock"></i>
      </span>
      </div>
      <p id="passwordHelp" class="help is-danger"></p>
      </div>
      <div class="field">
      <label class="label">Password Strength</label>
      <progress id="passwordStrength" class="progress is-danger" value="0" max="5" />
      </div>


      Script



      const fromEvent = rxjs
      const map, filter = rxjs.operators

      document.addEventListener('DOMContentLoaded', () =>
      const passwordInput = document.getElementById('password')
      const passwordHelp = document.getElementById('passwordHelp')
      const passwordStrength = document.getElementById('passwordStrength')

      const passwordChanged$ = fromEvent(passwordInput, 'input')
      .pipe(
      map(x => x.target.value),
      map(zxcvbn)
      )

      passwordChanged$
      .pipe(map(password => password.score > 2 ? 'success' : 'danger'))
      .subscribe(state =>
      passwordInput.className = `input is-$state`
      passwordStrength.className = `progress is-$state`
      )

      passwordChanged$
      .subscribe(password => passwordHelp.innerHTML = password.feedback.warning )

      passwordChanged$
      .subscribe(password => passwordStrength.setAttribute('value', password.score + 1) )
      )








      share|improve this question












      share|improve this question




      share|improve this question








      edited May 24 at 20:15









      Igor Soloydenko

      2,697827




      2,697827









      asked May 24 at 14:34









      Matthew Smith

      1112




      1112




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          1
          down vote













          Each subscribe(...) invocation results in creating and returning a new Subscription unless special measures are taken (like .publish(), .share()...)




          Subscribing to observables



          Remember, observables are lazy. If you don’t subscribe nothing is going to happen. It’s good to know that when you subscribe to an observer, each call of subscribe() will trigger it’s own independent execution for that given observer. Subscribe calls are not shared among multiple subscribers to the same observable. — Luuk Gruijs




          Each Subscription



          • eats up a bit of resources;

          • is processed separately from the others;

          • and needs to be unsubscribed separately to release the resources.

          Therefore, if you have no special reasons, you should subscribe the least number of times. In your case, a single subscription is sufficient. You can still use separate functions to delegate them the actual work (setClassNames(), setWarning(), setStrength()).




          const fromEvent = rxjs
          const map, filter = rxjs.operators

          document.addEventListener('DOMContentLoaded', () =>
          const passwordInput = document.getElementById('password')
          const passwordHelp = document.getElementById('passwordHelp')
          const passwordStrength = document.getElementById('passwordStrength')

          const passwordChanged$ = fromEvent(passwordInput, 'input')
          .pipe(
          map(x => x.target.value),
          map(zxcvbn)
          )

          const setClassNames = password =>
          const state = password.score > 2 ? 'success' : 'danger';
          passwordInput.className = `input is-$state`
          passwordStrength.className = `progress is-$state`
          ;
          const setWarning = password => passwordHelp.innerHTML = password.feedback.warning ;
          const setStrength = password => passwordStrength.setAttribute('value', password.score + 1) ;

          passwordChanged$
          .subscribe(password =>
          setClassNames(password);
          setWarning(password);
          setStrength(password);
          );
          )





          share|improve this answer





















            Your Answer




            StackExchange.ifUsing("editor", function ()
            return StackExchange.using("mathjaxEditing", function ()
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            );
            );
            , "mathjax-editing");

            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "196"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );








             

            draft saved


            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195092%2fjavascript-and-rxjs-password-strength-indicator%23new-answer', 'question_page');

            );

            Post as a guest






























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            1
            down vote













            Each subscribe(...) invocation results in creating and returning a new Subscription unless special measures are taken (like .publish(), .share()...)




            Subscribing to observables



            Remember, observables are lazy. If you don’t subscribe nothing is going to happen. It’s good to know that when you subscribe to an observer, each call of subscribe() will trigger it’s own independent execution for that given observer. Subscribe calls are not shared among multiple subscribers to the same observable. — Luuk Gruijs




            Each Subscription



            • eats up a bit of resources;

            • is processed separately from the others;

            • and needs to be unsubscribed separately to release the resources.

            Therefore, if you have no special reasons, you should subscribe the least number of times. In your case, a single subscription is sufficient. You can still use separate functions to delegate them the actual work (setClassNames(), setWarning(), setStrength()).




            const fromEvent = rxjs
            const map, filter = rxjs.operators

            document.addEventListener('DOMContentLoaded', () =>
            const passwordInput = document.getElementById('password')
            const passwordHelp = document.getElementById('passwordHelp')
            const passwordStrength = document.getElementById('passwordStrength')

            const passwordChanged$ = fromEvent(passwordInput, 'input')
            .pipe(
            map(x => x.target.value),
            map(zxcvbn)
            )

            const setClassNames = password =>
            const state = password.score > 2 ? 'success' : 'danger';
            passwordInput.className = `input is-$state`
            passwordStrength.className = `progress is-$state`
            ;
            const setWarning = password => passwordHelp.innerHTML = password.feedback.warning ;
            const setStrength = password => passwordStrength.setAttribute('value', password.score + 1) ;

            passwordChanged$
            .subscribe(password =>
            setClassNames(password);
            setWarning(password);
            setStrength(password);
            );
            )





            share|improve this answer

























              up vote
              1
              down vote













              Each subscribe(...) invocation results in creating and returning a new Subscription unless special measures are taken (like .publish(), .share()...)




              Subscribing to observables



              Remember, observables are lazy. If you don’t subscribe nothing is going to happen. It’s good to know that when you subscribe to an observer, each call of subscribe() will trigger it’s own independent execution for that given observer. Subscribe calls are not shared among multiple subscribers to the same observable. — Luuk Gruijs




              Each Subscription



              • eats up a bit of resources;

              • is processed separately from the others;

              • and needs to be unsubscribed separately to release the resources.

              Therefore, if you have no special reasons, you should subscribe the least number of times. In your case, a single subscription is sufficient. You can still use separate functions to delegate them the actual work (setClassNames(), setWarning(), setStrength()).




              const fromEvent = rxjs
              const map, filter = rxjs.operators

              document.addEventListener('DOMContentLoaded', () =>
              const passwordInput = document.getElementById('password')
              const passwordHelp = document.getElementById('passwordHelp')
              const passwordStrength = document.getElementById('passwordStrength')

              const passwordChanged$ = fromEvent(passwordInput, 'input')
              .pipe(
              map(x => x.target.value),
              map(zxcvbn)
              )

              const setClassNames = password =>
              const state = password.score > 2 ? 'success' : 'danger';
              passwordInput.className = `input is-$state`
              passwordStrength.className = `progress is-$state`
              ;
              const setWarning = password => passwordHelp.innerHTML = password.feedback.warning ;
              const setStrength = password => passwordStrength.setAttribute('value', password.score + 1) ;

              passwordChanged$
              .subscribe(password =>
              setClassNames(password);
              setWarning(password);
              setStrength(password);
              );
              )





              share|improve this answer























                up vote
                1
                down vote










                up vote
                1
                down vote









                Each subscribe(...) invocation results in creating and returning a new Subscription unless special measures are taken (like .publish(), .share()...)




                Subscribing to observables



                Remember, observables are lazy. If you don’t subscribe nothing is going to happen. It’s good to know that when you subscribe to an observer, each call of subscribe() will trigger it’s own independent execution for that given observer. Subscribe calls are not shared among multiple subscribers to the same observable. — Luuk Gruijs




                Each Subscription



                • eats up a bit of resources;

                • is processed separately from the others;

                • and needs to be unsubscribed separately to release the resources.

                Therefore, if you have no special reasons, you should subscribe the least number of times. In your case, a single subscription is sufficient. You can still use separate functions to delegate them the actual work (setClassNames(), setWarning(), setStrength()).




                const fromEvent = rxjs
                const map, filter = rxjs.operators

                document.addEventListener('DOMContentLoaded', () =>
                const passwordInput = document.getElementById('password')
                const passwordHelp = document.getElementById('passwordHelp')
                const passwordStrength = document.getElementById('passwordStrength')

                const passwordChanged$ = fromEvent(passwordInput, 'input')
                .pipe(
                map(x => x.target.value),
                map(zxcvbn)
                )

                const setClassNames = password =>
                const state = password.score > 2 ? 'success' : 'danger';
                passwordInput.className = `input is-$state`
                passwordStrength.className = `progress is-$state`
                ;
                const setWarning = password => passwordHelp.innerHTML = password.feedback.warning ;
                const setStrength = password => passwordStrength.setAttribute('value', password.score + 1) ;

                passwordChanged$
                .subscribe(password =>
                setClassNames(password);
                setWarning(password);
                setStrength(password);
                );
                )





                share|improve this answer













                Each subscribe(...) invocation results in creating and returning a new Subscription unless special measures are taken (like .publish(), .share()...)




                Subscribing to observables



                Remember, observables are lazy. If you don’t subscribe nothing is going to happen. It’s good to know that when you subscribe to an observer, each call of subscribe() will trigger it’s own independent execution for that given observer. Subscribe calls are not shared among multiple subscribers to the same observable. — Luuk Gruijs




                Each Subscription



                • eats up a bit of resources;

                • is processed separately from the others;

                • and needs to be unsubscribed separately to release the resources.

                Therefore, if you have no special reasons, you should subscribe the least number of times. In your case, a single subscription is sufficient. You can still use separate functions to delegate them the actual work (setClassNames(), setWarning(), setStrength()).




                const fromEvent = rxjs
                const map, filter = rxjs.operators

                document.addEventListener('DOMContentLoaded', () =>
                const passwordInput = document.getElementById('password')
                const passwordHelp = document.getElementById('passwordHelp')
                const passwordStrength = document.getElementById('passwordStrength')

                const passwordChanged$ = fromEvent(passwordInput, 'input')
                .pipe(
                map(x => x.target.value),
                map(zxcvbn)
                )

                const setClassNames = password =>
                const state = password.score > 2 ? 'success' : 'danger';
                passwordInput.className = `input is-$state`
                passwordStrength.className = `progress is-$state`
                ;
                const setWarning = password => passwordHelp.innerHTML = password.feedback.warning ;
                const setStrength = password => passwordStrength.setAttribute('value', password.score + 1) ;

                passwordChanged$
                .subscribe(password =>
                setClassNames(password);
                setWarning(password);
                setStrength(password);
                );
                )






                share|improve this answer













                share|improve this answer



                share|improve this answer











                answered May 24 at 19:30









                Igor Soloydenko

                2,697827




                2,697827






















                     

                    draft saved


                    draft discarded


























                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195092%2fjavascript-and-rxjs-password-strength-indicator%23new-answer', 'question_page');

                    );

                    Post as a guest













































































                    Popular posts from this blog

                    Greedy Best First Search implementation in Rust

                    Function to Return a JSON Like Objects Using VBA Collections and Arrays

                    C++11 CLH Lock Implementation