0

Не понимаю, в чём проблема. Нужно сделать POST-запрос на сервер (через fetch). Запрос должен происходить при нажатии на кнопку. Но когда я это делаю, появляется ошибка:

POST http://localhost:8888/latest_dz_web/calculator-yii2/web/api/calculate-price 500 (Internal Server Error)

{name: 'PHP Warning', message: 'Undefined property: stdClass::$month', code: 2, type: 'yii\base\ErrorException', file: '/Applications/MAMP/htdocs/latest_dz_web/calculator-yii2/controllers/ApiController.php', …}

Код js:

const requestCalcURL = 'http://localhost:8888/latest_dz_web/calculator-yii2/web/api/calculate-price'

function sendGetRequest(method, url) { return fetch(url).then(response => { return response.json() }) }

let chooseType = null; let chooseMonth = null; let chooseTonnage = null;

let body = { tonnage: '', raw_types: '', month: '' }

function getTonnage(event) { chooseTonnage = event.target.innerHTML; console.log(chooseTonnage); body.tonnage = chooseTonnage }

function getType(event) { chooseType = event.target.innerHTML; console.log(chooseType); body.raw_types = chooseType }

function getMonth(event) { chooseMonth = event.target.innerHTML; console.log(chooseMonth); body.month = chooseMonth }

const headers = { 'Content-type': 'application/json' }

function sendCalcRequestF(method, url, body) { return fetch(url, { method: method, body: JSON.stringify(body), headers: headers }).then(response => { return response.json() }) }

const body2 = { tonnage: 25, raw_types: "шрот", month: "январь" }

sendCalcRequestF('POST', requestCalcURL, body2) .then(data => console.log(data)) .catch(err => console.log(err))

            function echo() {
                console.log("body", body)
                console.log("JSON.stringify(body)", JSON.stringify(body))
                console.log("body2", body2)
                console.log("JSON.stringify(body2)", JSON.stringify(body2))
            }

Кнопка в html-файле:

<button class="btn btn-success" 
                onclick="
                sendCalcRequestF('POST', requestCalcURL, body)
                .then(data => console.log(data))
                .catch(err => console.log(err))
                "
                ondblclick="echo()"
                >
                рассчитать
            </button>

echo() - функция, которая выводит body в консоль (для проверки).

Причём с другим телом (body2) этот запрос работает нормально, и если выбрать значения переменных тела такими же, как в body2, то body и body2 получаются вообще совершенно одинаковыми. Но с телом body, переменные для которого не задаются изначально, а получены из клика по нужному варианту списка, запрос не работает.

Также прикреплю код html:

<div class="selector" id="selector_one">
                <div>
                    <transition name="tr" mode="out-in"> 
                        <span v-if="!show1" @click="show1 = !show1" key="raw_type">тип сырья</span>
                        <span v-else @click="show1 = !show1" key="select_raw_type">выберите тип сырья:</span>
                    </transition>
                    <transition name="tr">
                        <ul v-if="show1">
                            <li onclick="getType(event)" v-for="i in types"> {{ i }} </li>
                        </ul>
                    </transition>
                    </div>
            </div>
        &lt;div class=&quot;selector&quot; id=&quot;selector_two&quot;&gt;
            &lt;div&gt;
                &lt;transition name=&quot;tr&quot; mode=&quot;out-in&quot;&gt; 
                    &lt;span v-if=&quot;!show2&quot; @click=&quot;show2 = !show2&quot; key=&quot;raw_type&quot;&gt;месяц&lt;/span&gt;
                    &lt;span v-else @click=&quot;show2 = !show2&quot; key=&quot;select_raw_type&quot;&gt;выберите месяц:&lt;/span&gt;
                &lt;/transition&gt;
                &lt;transition name=&quot;tr&quot;&gt;
                    &lt;ul v-if=&quot;show2&quot;&gt;
                        &lt;li onclick=&quot;getMonth(event)&quot; v-for=&quot;j in months&quot;&gt; {{ j }} &lt;/li&gt;
                    &lt;/ul&gt;
                &lt;/transition&gt;
                &lt;/div&gt;
        &lt;/div&gt;

        &lt;div class=&quot;selector&quot; id=&quot;selector_sri&quot;&gt;
            &lt;div&gt;
                &lt;transition name=&quot;tr&quot; mode=&quot;out-in&quot;&gt; 
                    &lt;span v-if=&quot;!show3&quot; @click=&quot;show3 = !show3&quot; key=&quot;raw_type&quot;&gt;тоннаж&lt;/span&gt;
                    &lt;span v-else @click=&quot;show3 = !show3&quot; key=&quot;select_raw_type&quot;&gt;выберите тоннаж:&lt;/span&gt;
                &lt;/transition&gt;
                &lt;transition name=&quot;tr&quot;&gt;
                    &lt;ul v-if=&quot;show3&quot;&gt;
                        &lt;li onclick=&quot;getTonnage(event)&quot; v-for=&quot;k in tonnages&quot;&gt; {{ k }} &lt;/li&gt;
                    &lt;/ul&gt;
                &lt;/transition&gt;
                &lt;/div&gt;
        &lt;/div&gt;


        &lt;div id=&quot;button&quot;&gt;
            &lt;button class=&quot;btn btn-success&quot; 
            onclick=&quot;
            sendCalcRequestF('POST', requestCalcURL, body)
            .then(data =&gt; console.log(data))
            .catch(err =&gt; console.log(err))
            &quot;
            ondblclick=&quot;echo()&quot;
            &gt;
            рассчитать
        &lt;/button&gt;
        &lt;/div&gt;

И код ApiController:

<?php

namespace app\controllers;

use app\models\Month; use app\models\Raw_types; use app\models\Tonnage; use app\models\ApiCalculateForm; use yii\filters\VerbFilter; use yii\helpers\ArrayHelper;

use Yii;

class ApiController extends \yii\rest\Controller { public function behaviors() { return ArrayHelper::merge(parent::behaviors(), [ 'verbs' => [ 'class' => VerbFilter::class, 'actions' => [ 'get-data' => ['get'], 'calculate-price' => ['POST'], ], ], ]); }

public function actionCalculatePrice() {
    \Yii::$app-&gt;response-&gt;format = \yii\web\Response::FORMAT_JSON;

    $request = (object)json_decode(Yii::$app-&gt;request-&gt;getRawBody());

    $model = new ApiCalculateForm();

    $model-&gt;month = $request-&gt;month;
    $model-&gt;raw_types = $request-&gt;raw_types;
    $model-&gt;tonnage = $request-&gt;tonnage;

    if ($model-&gt;validate() === false) {
        return $model-&gt;getErrors();
    }

    return [
        'price' =&gt; $model-&gt;calculatePrice(),
        'price_list' =&gt; [$model-&gt;raw_types =&gt; $model-&gt;generatePriceList()],
    ];
}

}

esa
  • 17
  • 4
  • 1
    А вы через отладку посмотрите внимательно, что у вас лежит в $request или в Yii::$app->request->getRawBody() и тогда догадываться не надо будет – Алексей Шиманский Nov 20 '23 at 15:30
  • 1
    А вообще попробуйте сделать не (object)json_decode(Yii::$app->request->getRawBody()); а просто json_decode(Yii::$app->request->getRawBody()); – Алексей Шиманский Nov 20 '23 at 15:31
  • @АлексейШиманский глупый вопрос, но... как посмотреть это в отладке?) Единственное, до чего додумался - сделать вот так: return [ 'price' => $model->calculatePrice(), 'price_list' => [$model->raw_types => $model->generatePriceList()], 'request' => var_dump($request), 'Yii::$app->request->getRawBody()' => var_dump(Yii::$app->request->getRawBody()) ]; и попытаться отправить такой запрос через postman (с телом body2); в таком случае он выдал null и в request, и в Yii::$app->request->getRawBody(); но это, кажется, вообще не то, что мне нужно былло сделать?) – esa Nov 20 '23 at 19:02
  • 1
    https://ru.stackoverflow.com/a/701146/191482 .... – Алексей Шиманский Nov 20 '23 at 19:09

0 Answers0