0

I have a page which two users play each other on that and I set some global variables at the top of my javascript code:

    myScore             = 0;
    OpponentScore       = 0;

    winner = loser = loser_point = winner_point = dual = null;

and check user answers in another part of code while server broadcasts user's answer :

I'm using laravel echo and pusher

            .listen('UserAnswered', (e) =>  {

                $(document).find('.myAvatar').find('i.fa').removeClass('animated');
                $(document).find('.myAvatar').find('i.fa').removeClass('heartBeat');
                $(document).find('.myAvatar').find('i.fa').removeClass('swing');

                $(document).find('.opponentAvatar').find('i.fa').removeClass('animated');
                $(document).find('.opponentAvatar').find('i.fa').removeClass('heartBeat');
                $(document).find('.opponentAvatar').find('i.fa').removeClass('swing');

                if( e.user_id === parseInt("{{ Auth::id() }}", 10) )
                {
                    //this user answered
                    if( e.result == 1 )
                    {
                        myScore++;
                        $('.myResult').find('.target').text(myScore);
                        $('.myAvatar').find('i.fa').addClass('heartBeat animated');
                    }
                    else
                    {
                        $('.myAvatar').find('i.fa').addClass('swing animated');
                    }
                }
                else
                {
                    //opponent answered
                    if( e.result == 1 )
                    {
                        OpponentScore++;
                        $('.opponentResult').find('.target').text(OpponentScore);
                        $('.opponentAvatar').find('i.fa').addClass('heartBeat animated');
                    }
                    else
                    {
                        $('.opponentAvatar').find('i.fa').addClass('swing animated');
                    }

                }

            });

and I have a method named setScoreboard which set winner, loser, winner_point and loser_point, when the game is finished .

Set Scorebaord function :

        /**
         * Set Scoreboard Function
         */
        function setScoreboard() {

            window.Echo.disconnect();

            if( myScore > OpponentScore )
            {

                winner       = "{{ json_encode(Auth::id()) }}";
                loser        = OpponentId;
                winner_point = myScore;
                loser_point  = OpponentScore;
                dual         = false;
                $(document).find('input[name="game_id"]').val(String(gameId));


                $(document).find('input[name="winner"]').val(winner);
                $(document).find('input[name="loser"]').val(loser);
                $(document).find('input[name="winner_point"]').val(String(myScore));
                $(document).find('input[name="loser_point"]').val(String(OpponentScore));
                $(document).find('input[name="dual"]').val('false');

                //submit hidden form
                $(document).find('form[name="setResultForm"]').submit();
            }
            else if (OpponentScore > myScore)
            {
                winner          = OpponentId;
                loser           = "{{ json_encode(Auth::id()) }}";
                winner_point    = OpponentScore;
                loser_point     = myScore;
                dual            = false;
                $(document).find('input[name="game_id"]').val(String(gameId));

                $(document).find('input[name="winner"]').val(winner);

                $(document).find('input[name="loser"]').val(loser);
                $(document).find('input[name="winner_point"]').val(String(OpponentScore));
                $(document).find('input[name="loser_point"]').val(String(myScore));
                $(document).find('input[name="dual"]').val('false');

                //submit hidden form
                $(document).find('form[name="setResultForm"]').submit();

            }
            else if (OpponentScore === myScore)
            {

                winner = "{{ json_encode(Auth::id()) }}";
                loser  = OpponentId;
                winner_point = loser_point = myScore;
                dual = true;
                $(document).find('input[name="game_id"]').val(String(gameId));
                {{--$(document).find('input[name="winner"]').val(String(parseInt("{{ json_encode(Auth::id()) }}", 10)));--}}
                $(document).find('input[name="winner"]').val(winner);
                // $(document).find('input[name="loser"]').val(String(OpponentId));
                $(document).find('input[name="loser"]').val(loser);
                $(document).find('input[name="winner_point"]').val(String(OpponentScore));
                $(document).find('input[name="loser_point"]').val(String(OpponentScore));
                $(document).find('input[name="dual"]').val('true');

                //submit hidden form
                $(document).find('form[name="setResultForm"]').submit();

            }

Everything looks good and the code works fine, but randomly in one side, winner or loser would be null!

PLAYER ONE:

player one submitted result

PLAYER TWO:

player two submitted result

As the code is the same for both users side, Does anyone know why is that?

jhpratt
  • 6,841
  • 16
  • 40
  • 50
Kiyarash
  • 2,437
  • 7
  • 32
  • 61
  • Maybe your case is that one where [Auth::id() returns null in laravel](https://stackoverflow.com/questions/52055866/authid-returns-null-laravel)? – andy Jul 19 '19 at 17:07
  • @andy I have a middleware which redirect user to login page if user is not logged in – Kiyarash Jul 19 '19 at 17:09
  • Is there any correlation between moments of occurence and length of session? Maybe session is gone due to expired token? Maybe laravel mishandles redirects (if after login there is redir back to initiatig URL)? – andy Jul 19 '19 at 17:21
  • can you add the code block of where OpponentId initialize – Onur Gelmez Jul 19 '19 at 18:11

1 Answers1

0

Randomly appearing issues can be crazy frustrating!

In this case, it appears that the issue is with your assignment of the winner or loser variable on the blade page. Depending upon which of the conditions is true (OpponentScore vs myScore) you have a 'random' chance at sending a particular variable through to the server. This is almost certainly the cause of the 'random' appearing behavior - you have the possibility of sending a different (potentially) bad variable in each if-check.

The way to trace and fix this is to set a console log directly under each of the if-check block assignment sections like this:

if( myScore > OpponentScore )
    {
       winner       = "{{ json_encode(Auth::id()) }}";
       loser        = OpponentId;
       console.log('myScore > OppScore block results:  winner = " + winner + "  loser = " + loser);
    }

Do this for each. Here you can figure out if the JS var OpponentId is not being assigned or if the Laravel Auth::user()->id is not being assigned. If JS, the fix is on the blade page. If Laravel Auth, the fix might be in the session or might be on a route TO this page wherein there is no middleware for auth (thus this game page is auth free).

As you've said the user needs to get logged in to be on this page, I suspect it is an error with the assignment of the JS var, OpponentId, which will be shown in the console, and can be fixed on that page. I don't see where this is assigned, so I can't say for sure - but if this shows up in console as undefined, you'll know what the problem is.

Watercayman
  • 7,970
  • 10
  • 31
  • 49