Събмитване на AJAX заявка за смяна на снимка не ми пълни базата от данни
Имам форма, която е писана по документацията на Symfony и работи добре, но рефрешва страницата при събмит затова реших да направя AJAX заявка да сменям снимката без да обновявам цялата страница. Проблемът е че съм написал заявката, прехвърлям данните, но незнайно защо името на новата снимка не се появява в базата или в папката където ги съхранявам. Това ми е кодът в момента(контролерът):
/**
* @Route("/upload", name="uploadpic")
* @param Request $request
* @return JsonResponse|\Symfony\Component\HttpFoundation\Response
*/
public function uploadAction(Request $request){
if(!$request->isXmlHttpRequest()){
return new JsonResponse(
array(
'message' => 'Error',
'status' => 'Not received'
), 400);
}
$user = $this->get('security.token_storage')->getToken()->getUser();
$formed = $this->createForm(UserPic::class, $user);
$formed->handleRequest($request);
if(isset($request->request)) {
$postPicture = $request->files->get('picture_data');
$file = $user->getUserPic();
$fileName = $postPicture->generateUniqueFileName() . '.' . $file->guessExtension();
$file->move(
$this->getParameter('users_directory'),
$fileName
);
$user->setUserPic($fileName);
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
return $this->render('default/index.html.twig',
['formed' => $formed->createView()]);
}
}
Пробвах и с $postPicture = $request->request->get('picture_data'); вместо $postPicture = $request->request->get('picture_data'); , защото принципно така работи като пращам текст от textarea с AJAX към базата.
Пробвах и $fileName = $this->generateUniqueFileName() . '.' . $file->guessExtension(); вместо $fileName = $postPicture->generateUniqueFileName() . '.' . $file->guessExtension();, защото така е писано в документацията, но и така не работи.
Кодът ми на AJAX request-а:
$("#submit_pic").on('click', function(event){
event.preventDefault();
event.stopPropagation();
$.ajax({
type: "POST",
url: "/profile",
data: {
picture_data: new FormData($("#pic_data")[0])
},
processData: false,
contentType: false,
success: function () {
console.log();
},
error: function () {
console.log("Error here");
}
});
});
Пробвах с променяне на picture_data: $("#pic_data").serialize() с picture_data: new FormData($("#pic_data")[0]), защото четох един пост в stackoverflow че не работело така. Не разбирам защо не сетва нов image като AJAX-а дори не изплюва грешка.
Промених пътя да е "/upload", признавам че е недоглеждане от моя страна, но сега ми гъми с 500 internal server error. Дали не предавам данните правилно? Пробвах и със .serilize и с new FormData и все същата грешка...
Редактирах си поста.
Това ми е темплейта ако искате да погледнете, но там всичко е наред май. Грешката идва от AJAX-а, мисля че не стига изобщо до контролера:
{% if app.user.userPic is null %} <div class="" id="imageUpload"> <p> <label for="pic_data"> <img src="{{ asset('/pictures/anonimous.jpg') }}" class="rounded-circle" id="userPic"/> </label> <br/> </p> <form method="POST" enctype="multipart/form-data" action="{{ path('uploadpic') }}"> <p> <input type="file" id="pic_data" name="app_bundle_user_pic[userPic]" required> </p> <button type="submit" id="submit_pic" name="app_bundle_user_pic[Change]" class="btn btn-success btn-sm"> Change </button> </form> </div> {% else %} <div class="" id="imageUpload"> <p> <label for="pic_data"> <img src="{{ asset('/uploads/images/'~app.user.userPic) }}" class="rounded-circle" id="userPic"/> </label> <br/> </p> <form method="POST" enctype="multipart/form-data" action="{{ path('uploadpic') }}"> <p> <input type="file" id="pic_data" name="app_bundle_user_pic[userPic]" required> </p> <button type="submit" id="submit_pic" name="app_bundle_user_pic[Change]" class="btn btn-success btn-sm"> Change </button> </form> </div> {% endif %}Може да видиш защо ти дава 500, ако си с хром F12, network taba, отваряш /upload и отиваш на response.
var_dump-а на
не ми връща нищо като информация, имам сложен exit след него обаче и като спра скрипта тук:
var_dump($request->files->all()); exit(); $file = $user->getUserPic(); $fileName = $postPicture->generateUniqueFileName() . '.' . $file->guessExtension(); $file->move( $this->getParameter('users_directory'), $fileName );ми връща 'success' (този success си го слoжих като console.log , при success на ajax-а). Иначе пак си гърми с 500 ако го оставя така, пробвах и с
dump($request->files->all());
пак нищо не излиза...
П.С. data я промених на :
data: new FormData($("#pic_data")[0]) както ме посъветва и достъпвам в контролера по име:$postPicture = $request->files->get('app_bundle_user_pic[userPic]');Пак казвам, че с хрома може да видиш респонса и защо точно ти дава еррор 500.
При
ми дава
а при
връща
Мисля че не намира снимката
guessExtension() трябва да е на файла, който ъплоадваш. Т.е. $postPicture->guessExtension();
generateUniqueFileName() ... нещо не мога да открия по документацията почти нищо. Възможно е да е deprecated. Ползвай uniqid();
$file = $request->files->get('app_bundle_user_pic[userPic]'); $fileName = $this->generateUniqueFileName() . '.' . $file->guessExtension();дава същата грешка:
Call to a member function guessExtension() on null (500 Internal Server Error)
generateUniqueFileName() e изнесено на функция, която прави същото което ти казваш да прави:
private function generateUniqueFileName() { return md5(uniqid()); }П.С. Тук ли да оставя скайп, че не намирам опция за л.с.(съжалявам за нууб въпроса)
Намери ме: live:1c00b8bcb2e2bdc9
getUserPic() вероятно си е стринг, защото сигурно е колона в базата т.е. така е зададено в ентитито User. Да не би да трябва да ползваш само $postPicture? И може да погледнеш и дали content type-а ти е multipart/form data, защото иначе файлове не могат да се пращат.
P..S.: За да не стават такива грешки като "нямам такъв метод" е хубаво да ползвате РНР като всеки един друг по-типизиран език, а именно, да си следите типовете и да ги позвате само като такива. Да няма ситуации, в които една променлива може да бъде стринг, а в друга ситуация да е file, например. :)
Ами не, то си ти казва, че не намира такава функция. По-скоро ползвай uniqid()