Соглашение об именах v-модели для Vuejs и Axios в запросе POST (проблемы с кодированием объекта Vue в JSON)

это будет супер долгое время!

По общему признанию, я не очень хороший фронтенд-дизайнер, и мои навыки работы с Javascript оставляют желать лучшего.

TL: DR - Чем рабочий код отличается от объекта данных в кодировке JSON (продавец) в нерабочем коде в отношении запроса Axios POST? Разве они не должны давать такой же результат?

Сначала немного предыстории: я создаю бэкэнд Laravel REST с полным набором функций, валидаторами форм, политиками, работами. Я протестировал бэкэнд с клиентом ARC REST для Chrome и убедился, что мой бэкэнд полностью работоспособен.

Проблема: при разработке интерфейса с использованием Vuejs, Vue-Router и Axios у меня возникли проблемы с отправкой данных на сервер. В частности, это сбой проверки формы с ошибкой HTTP 422. Я сузил эту проблему, чтобы она была связана с инкапсуляцией объекта в Vue или Axios.

Вот нерабочий компонент Vue:

    <div class="panel panel-default">
        <div class="panel-heading">Create Merchant</div>
        <div class="panel-body">
            <form action="#" @submit.prevent="createMerchant()">
                Primary
                <input v-model="merchant.primary" type="text" name="primary" class="form-control" autofocus>
                Alternate
                <input v-model="merchant.alternate" type="text" name="alternate" class="form-control">
                Contact
                <input v-model="merchant.contact" type="text" name="contact" class="form-control">
                Street
                <input v-model="merchant.street" type="text" name="street" class="form-control">
                City
                <input v-model="merchant.city" type="text" name="city" class="form-control">
                State
                <input v-model="merchant.state" type="text" name="state" class="form-control">
                Country
                <input v-model="merchant.country" type="text" name="country" class="form-control">
                Postal Code
                <input v-model="merchant.postalCode" type="text" name="postalCode" class="form-control">
                <button type="submit" class="btn btn-primary">Create Merchant</button>
            </form>
        </div>
    </div>

    <div v-if='errors && errors.length' class="panel panel-default">
        <div class="panel-heading">Error</div>
        <div class="panel-body">
            <ul>
                <li v-for='error of errors'>
                    {{error.message}}
                </li>
            </ul>
        </div>
    </div>

</div>
</template>

<script>
export default {
    data() {
        return {
            merchant: {
                primary: '',
                alternate: '',
                contact: '',
                street: '',
                city: '',
                state: '',
                country: '',
                postalCode: ''
            },
            errors: []
        };
    },

    methods: {
        createMerchant() { console.log(JSON.stringify(this.merchant));
            axios.post('/payment-gateway/public/api/v1/merchant', JSON.stringify(this.merchant))
            .then((response) => {
                console.log(response.data.id);
                this.$router.push({ name: 'merchantList' });
            })
            .catch(e => {
                this.errors.push(e);
            });
        }
    }
}
</script>

Публикуемые данные, с моей точки зрения, кажутся правильными:

{"primary": "Widget Company", "alternate": "Widget Co", "contact": "555-555-0055", "street": "123 Main St", "city": "Olympia", " state ":" WA "," country ":" USA "," postalCode ":" 98501 "}

Но приведенный выше код всегда приводит к ошибке HTTP 422.

Теперь, что меня смущает, это рабочий код:

    <div class="panel panel-default">
        <div class="panel-heading">Create Merchant</div>
        <div class="panel-body">
            <form action="#" @submit.prevent="createMerchant()">
                Primary
                <input v-model="merchant.primary" type="text" name="primary" class="form-control" autofocus>
                Alternate
                <input v-model="merchant.alternate" type="text" name="alternate" class="form-control">
                Contact
                <input v-model="merchant.contact" type="text" name="contact" class="form-control">
                Street
                <input v-model="merchant.street" type="text" name="street" class="form-control">
                City
                <input v-model="merchant.city" type="text" name="city" class="form-control">
                State
                <input v-model="merchant.state" type="text" name="state" class="form-control">
                Country
                <input v-model="merchant.country" type="text" name="country" class="form-control">
                Postal Code
                <input v-model="merchant.postalCode" type="text" name="postalCode" class="form-control">
                <button type="submit" class="btn btn-primary">Create Merchant</button>
            </form>
        </div>
    </div>

    <div v-if='errors && errors.length' class="panel panel-default">
        <div class="panel-heading">Error</div>
        <div class="panel-body">
            <ul>
                <li v-for='error of errors'>
                    {{error.message}}
                </li>
            </ul>
        </div>
    </div>

</div>
</template>

<script>
export default {
    data() {
        return {
            merchant: {
                primary: '',
                alternate: '',
                contact: '',
                street: '',
                city: '',
                state: '',
                country: '',
                postalCode: ''
            },
            errors: []
        };
    },

    methods: {
        createMerchant() { console.log(JSON.stringify(this.merchant));
            axios.post('/payment-gateway/public/api/v1/merchant', {
                primary: this.merchant.primary,
                alternate: this.merchant.alternate,
                contact: this.merchant.contact,
                street: this.merchant.street,
                city: this.merchant.city,
                state: this.merchant.state,
                country: this.merchant.country,
                postalCode: this.merchant.postalCode
            })
            .then((response) => {
                console.log(response.data.id);
                this.$router.push({ name: 'merchantList' });
            })
            .catch(e => {
                this.errors.push(e);
            });
        }
    }
}
</script>

Итак, мой вопрос: чем рабочий код отличается от объекта данных в кодировке JSON (продавец) в нерабочем коде?


person boldbesusiax    schedule 12.11.2017    source источник
comment
Один вы отправляете объект, другой - строку. Я предполагаю, что вам нужно что-то сделать с ContentType первого, чтобы сообщить ему, что данные находятся в формате JSON.   -  person webnoob    schedule 13.11.2017
comment
Спасибо за ваш вклад! Разве объект не будет преобразован в строку при его сериализации с помощью JSON.stringify ()? Мне нужно будет проверить тип кодировки, я думаю, что оставил его в 'application / x-www-urlencoded', что тоже может меня облажать (ууу!)   -  person boldbesusiax    schedule 13.11.2017
comment
Извините, я не видел ответа :) Объект, конечно, будет преобразован в строку, но, когда он это делает, я также могу представить, что он устанавливает ContentType на application/json. Сообщите мне, как проходит ваше тестирование, и я добавлю ответ, если это проблема. Не торопитесь добавлять еще, потому что я не уверен на 100%.   -  person webnoob    schedule 13.11.2017
comment
Установка типа контента на JSON была золотым билетом! Теперь я могу передать сериализованный объект своим почтовым функциям, и он работает как шарм. Ваше здоровье! Ответил бы раньше, но у приложения Stack overflow есть привычка не отправлять уведомления.   -  person boldbesusiax    schedule 16.11.2017
comment
Рад слышать. Добавили ответ для следующего бота, который сталкивается с проблемой :)   -  person webnoob    schedule 16.11.2017


Ответы (1)


В одном случае вы отправляете объект, а в другом - строку. Хотя в конечном итоге они оба будут переданы как строка, когда вы передаете объект, ContentType устанавливается под капотом на application/json.

При этом, если вы установите ContentType в application/json для того, которое вы передаете в виде строки, он отсортирует проблему.

person webnoob    schedule 16.11.2017