Symfony Form FileType через AJAX: ошибка проверки isSubmitted () всегда ложна с processData: false - PullRequest
0 голосов
/ 09 декабря 2018

Я делал загрузку файлов с AJAX JQUERY в прошлом, но сейчас я пытаюсь сделать то же самое с Symfony FileType.

Проблема в том, что в нормальном рабочем процессе нам нужно добавить contentType: false, processData: false, но это, кажется, приводит к следующей ошибке Symfony: Cannot check if an unsubmitted form is valid. Call Form::isSubmitted() before Form::isValid().

, поэтому isSubmitted() всегда ложно, и я предполагаю, что из-за processData: false

я нахожусь в полной потере накак решить эту проблему, потому что, если я не выполняю contentType: false, AJAX-запрос вылетает.В документации Symfony нет содержания.

JAVASCRIPT:

const form_data = $('#newBrandForm').serializeArray();
const json = serializeAsObject(form_data)

    const files = document.getElementById('new_brand_group_logo_logoFile').files;

    if (files.length > 0) {

        let formData = new FormData();

        for (let x = 0; x < files.length; x++) {
            formData.append("attachements", files[x]);
        }

        json['new_brand[group_logo][logoFile]'] = formData

    }

    $.ajax({
        url: `/new-brand-form-handle`,
        type: 'POST',
        cache: false,
        contentType: false,
        processData: false,
        data: json
    })

CONTROLLER

function brandFormHandle(Request $request) {

    $em = $this->getDoctrine()->getManager();

    $brandEntity = new Brand();

    // create form
    $form = $this->createForm(NewBrandType::class, $brandEntity);

    // handle
    $form->handleRequest($request); // CRASH HERE

    if ($form->isSubmitted() && $form->isValid()) { 

        $brand = $form->getData();

        // move file
        $someNewFilename = 'newBrand'.'-logo';
        $file = $form['attachment']->getData();
        $file->move($this->directory, $someNewFilename);

        try {

            $em->persist($brand);
            $em->flush();

            $status = 'Brand added';

        } catch (Exception $ex) {
            return $this->json([2, 'insertion error'.$ex]);
        }
        return $this->json([1, $status]);
    }

 //....

}

$request DUMP Так что я могу видеть файлы там, но смотриткак форма это просто объект, поэтому я не уверен, что это может быть проблемой?

Request {#51 ▼
+attributes: ParameterBag {#71 ▶}
+request: ParameterBag {#87 ▼
#parameters: array:1 [▼
  "form" => "[object Object]"
]
}
+query: ParameterBag {#70 ▶}
+server: ServerBag {#35 ▶}
+files: FileBag {#73 ▶}
+cookies: ParameterBag {#72 ▶}
+headers: HeaderBag {#82 ▶}
#content: null
#languages: null
#charsets: null
#encodings: null
#acceptableContentTypes: null
#pathInfo: "/new-brand-form-handle"
#requestUri: "/new-brand-form-handle"
#baseUrl: ""
#basePath: null
#method: "POST"
#format: null
#session: Closure {#111 ▶}
#locale: null
#defaultLocale: "en"
-isHostValid: true
-isForwardedValid: true
basePath: ""
format: "html"
}

// это дамп из console.log (json), обратите внимание, что файла нет;Я не уверен, что это нормально

Object
 new_brand[group_description][description]: "description"
 new_brand[group_identification][city]: ""
 new_brand[group_identification][country]: "AU"
 new_brand[group_identification][name]: "name"
 new_brand[group_identification][postcode]: ""
 new_brand[group_identification][streetAdd]: ""
 new_brand[group_identification][street]: "street"
 new_brand[group_identification][website]: "website"
 new_brand[group_logo][logoURL]: "web" 

1 Ответ

0 голосов
/ 12 декабря 2018

Я не знаю, почему вы смешиваете разные подходы (используя serializeArray вместе с FormData), а не просто придерживаетесь FormData.

Похоже, что вы передаете неправильно отформатированный объект json как данные в вашем запросе ajax, так как поле json ['new_brand [group_logo] [logoFile]'] содержит formData и, следовательно, это недопустимый объект json.

На самом деле, если вы используете веточку для визуализации своей формы (что, я полагаю, вы делаете), все, что вам нужно сделать, это:

var form = $('#newBrandForm')[0]; // You need to use standard javascript object here
var formData = new FormData(form);

$.ajax({
    url: `/new-brand-form-handle`,
    type: 'POST',
    cache: false,
    contentType: false,
    processData: false,
    data: formData
});

Теперь вы должны правильно заполнить форму в своемконтроллер.

...