Как я могу сгенерировать ошибку доступа и сообщение об ошибке, оставив пользователя на странице?

В приложениях laravel / jquery, если мне нужно проверить, зарегистрирован ли пользователь, я делаю в контроллере:

$loggedUser = Auth::user();
if ( empty($loggedUser->id) ) {
    return response()->json(['error_code'=> 1, 'message'=> "You must be logged!"],HTTP_RESPONSE_INTERNAL_SERVER_ERROR);
}

поскольку мне не нужно оставлять пользователя со страницы, а только ограничивать некоторые функции, я показываю сообщение об ошибке выше, используя библиотеку bootstrapGrowl. Теперь с laravel 7 / livewire 1.3 / turbolinks: 5 / alpine @ v2 я ищу, как я могу сгенерировать ошибку и показать аналогичное сообщение об ошибке, оставляя пользователя на странице?

ОБНОВЛЕНО:

Позвольте мне объяснить это подробным примером: в приложениях laravel / jquery, которые у меня есть в коде JS:

var quiz_quality_radio= $('input[name=quiz_quality_radio]:checked').val()
var href = this_frontend_home_url + "/make-quiz-quality";
$.ajax( {
    type: "POST",
    dataType: "json",
    url: href,
    data: {"quiz_quality_id": quiz_quality_radio, "vote_id": this_vote_id, "_token": this_csrf_token},
    success: function( response )
    {
        $('input[name=quiz_quality_radio]:checked').prop('checked', false);
        frontendVote.showQuizQualityResults()
        popupAlert("Thank you for rating ! Your rate was added!", 'success')
    },
    error: function( error )
    {
        $('input[name=quiz_quality_radio]:checked').prop('checked', false);
        popupAlert(error.responseJSON.message, 'danger') // 'info', 'success'
    }
});

и относительное действие при контроле:

public function make_quiz_quality(Request $request)
{
    $requestData     = $request->all();
    $quiz_quality_id = ! empty($requestData['quiz_quality_id']) ? $requestData['quiz_quality_id'] : '';
    $vote_id         = ! empty($requestData['vote_id']) ? $requestData['vote_id'] : '';

    if ( ! Auth::check()) {
        return response()->json(['message' => "To rate you must login to the system !"], HTTP_RESPONSE_BAD_REQUEST);
    }
    if (empty($quiz_quality_id)) {
        return response()->json([
            'message'         => "To rate you must select quiz quality !",
            'quiz_quality_id' => $quiz_quality_id
        ], HTTP_RESPONSE_OK);
    }

    $vote = Vote::find($vote_id);
    if ($vote === null) {
        return response()->json([ 'message' => "Vote Item # " . $vote_id . " not found !"],HTTP_RESPONSE_NOT_FOUND);
    }
    $loggedUser = Auth::user();

    $found_count = QuizQualityResult
        ::getByVoteIdAndUserId($vote_id, $loggedUser->id)
        ->count();
    if ($found_count > 0) {
        return response()->json(['message' => "You have already rated '" . $vote->name . "' # vote !", 'vote_id' => $vote_id],
            HTTP_RESPONSE_BAD_REQUEST);
    }

    $newVoteItemUsersResult = new QuizQualityResult();
    try {
        $newVoteItemUsersResult->quiz_quality_id = $quiz_quality_id;
        $newVoteItemUsersResult->vote_id         = $vote_id;
        $newVoteItemUsersResult->user_id         = $loggedUser->id;
        DB::beginTransaction();
        $newVoteItemUsersResult->save();

        DB::commit();
    } catch (Exception $e) {
        DB::rollBack();

        return response()->json(['message' => $e->getMessage(), 'voteCategory' => null], HTTP_RESPONSE_INTERNAL_SERVER_ERROR);
    }

    return response()->json(['message' => '', 'id' => $newVoteItemUsersResult->id], HTTP_RESPONSE_OK_RESOURCE_CREATED);
} //     public function make_quiz_quality(Request $request)

и в случае ошибки, сгенерированной в блоке ошибок, я показываю сообщение с функцией popupAlert (реализованной с помощью bootstrapGrowl), не покидая страницу. Это то, что я хочу сделать в приложении livewire / turbolinks / alpine. Как я могу это сделать?

ОБНОВЛЕНО №2:

Это просто список элементов, за которые пользователь может проголосовать:

<div class="table-responsive">
    <table class="table text-primary">
        @foreach($quizQualityOptions as $key=>$next_quiz_quality_option)
            <tr>
                <td>
                    <input class="" type="radio" name="quiz_quality_radio" id="quiz_quality_radio_{{ $next_quiz_quality_option }}" value="{{ $key }}">
                    <label class="col-form-label" for="quiz_quality_radio_{{ $next_quiz_quality_option }}">{{ $next_quiz_quality_option }}</label>
                </td>
            </tr>
        @endforeach
    </table>
</div>

<div class="row p-3">
    <a class="btn btn-primary a_link" onclick="javascript:frontendVote.MakeQuizQuality()">Rate !</a>
</div>

с 2 ограничениями:

  1. Пользователь должен быть авторизован
  2. Любой зарегистрированный пользователь может проголосовать только после того, как эти 2 ошибки были зарегистрированы на сервере.

ОБНОВЛЕНО №3:

Я нашел решение с использованием аксиом, например:

    <button type="submit" class="btn btn-primary btn-sm m-2 ml-4 mr-4 action_link" @click.prevent="submitNewTodo()">
        Submit
    </button>



submitNewTodo() {
   console.log('submitNewTodo::')
    let is_insert= 1
    let current_toto_id= 1
    axios({
        method: (is_insert ? 'post' : 'patch'),
        url: '/api/todos' + (!is_insert ? "/" + current_toto_id : ''),
        data: {
            text : this.new_todo_text,
            priority : this.new_todo_priority
        },
    }).then((response) => {
        this.new_todo_text= ''
        this.new_todo_priority= ''
        this.loadTodosRows()
        popupAlert( 'Todo ' + (is_insert ? 'added' : 'updated') + ' successfully !', 'success' )
    }).catch((error) => {
        var validationErrors= convertObjectToArray(error.response.data.errors.text)
        
        this.validation_errors_text= ''
        validationErrors.map((next_error, index) => {
            if(next_error && typeof next_error[1] != "undefined" ) {
                this.validation_errors_text += '<li>'+next_error[1]+'</li>'
            }
        })

        popupErrorMessage(error.response.data.message)
    });

},

С его помощью я показываю сообщения об успехе и неудаче, когда мне нужно, но я вижу в этом большой недостаток, поскольку я использую livewire, и я хотел бы использовать livewire здесь, если это возможно ... Надеюсь, я четко объяснил, чего я хочу ...

Спасибо!


person Petro Gromovo    schedule 08.08.2020    source источник
comment
Пожалуйста, посмотрите ОБНОВЛЕНО \   -  person Petro Gromovo    schedule 13.08.2020
comment
Не могли бы вы включить код, который генерирует форму, включающую input [name = quiz_quality_radio]?   -  person Hugo    schedule 18.08.2020
comment
Извините, если я плохо поставил то, что хочу. Это был пример моих приложений PRIOR laravel / jquery. Мне нужно сделать подобное в приложении livewire / alpinejs   -  person Petro Gromovo    schedule 18.08.2020
comment
Конечно, было бы полезно иметь представление о том, как выглядит ваша форма, чтобы предложить альтернативу с помощью Alpine.js.   -  person Hugo    schedule 18.08.2020
comment
Пожалуйста, посмотрите ОБНОВЛЕНИЕ №2   -  person Petro Gromovo    schedule 18.08.2020
comment
Пожалуйста, посмотрите ОБНОВЛЕНИЕ №3   -  person Petro Gromovo    schedule 21.08.2020
comment
Ах, как мило, я собирался предложить аналогичное решение Alpine. Я не слишком хорошо знаком с Livewire, поэтому на данный момент мне особо не поможет.   -  person Hugo    schedule 21.08.2020
comment
Не могли бы вы привести пример / ссылку на аналогичное решение Alpine?   -  person Petro Gromovo    schedule 21.08.2020
comment
Добавлен ответ с использованием Alpine.js + axios на основе вашего исходного кода, есть некоторые переменные, которые, я не уверен, будут определены, но это должно быть хорошей отправной точкой.   -  person Hugo    schedule 21.08.2020


Ответы (1)


С Alpine.js и axios вы можете сделать что-то вроде этого, обратите внимание, что я не уверен, будут ли определены this_frontend_home_url, this_vote_id и this_csrf_token.

<div x-data="quiz()">
  <div>
    <div class="table-responsive">
      <table class="table text-primary">
        @foreach($quizQualityOptions as $key=>$next_quiz_quality_option)
        <tr>
          <td>
            <input x-model="selected_quiz" class="" type="radio" name="quiz_quality_radio"
              id="quiz_quality_radio_{{ $next_quiz_quality_option }}" value="{{ $key }}">
            <label class="col-form-label"
              for="quiz_quality_radio_{{ $next_quiz_quality_option }}">{{ $next_quiz_quality_option }}</label>
          </td>
        </tr>
        @endforeach
      </table>
    </div>

    <div class="row p-3">
      <a class="btn btn-primary a_link" @click="submitQuizQuality()">Rate !</a>
    </div>
  </div>
</div>
<script>
  function quiz() {
    return {
      selected_quiz: null,
      submitQuizQuality() {
        const url = this_frontend_home_url + "/make-quiz-quality";
        axios.post(url, {
          quiz_quality_id: this.selected_quiz,
          vote_id: this_vote_id, // no idea where this is coming from,
          _token: this_csrf_token // no idea where this is coming from
        }).then(() => {
          // reset "checked" state
          this.selected_quiz = null;
          frontendVote.showQuizQualityResults();
          popupAlert("Thank you for rating ! Your rate was added!", 'success');
        }).catch(error => {
          // reset "checked" state
          this.selected_quiz = null;
          if (error && error.response) {
            popupAlert(error.response.message, 'danger')
          }
        });
      }
    }
  }
</script>
person Hugo    schedule 21.08.2020
comment
Спасибо !, но я бы предпочел решение laravel-Livewire, если оно есть - person Petro Gromovo; 21.08.2020
comment
Как я уже упоминал, я не знаком с Livewire, но я считаю, что это сработает, имеет ли смысл принять это? - person Hugo; 21.08.2020