0

For some reason when I'm trying to upload a file using ajax I get the following error:

Uncaught TypeError: Illegal invocation
    at add (jquery-1.12.4.js:10073)
    at buildParams (jquery-1.12.4.js:10061)
    at buildParams (jquery-1.12.4.js:10055)
    at Function.jQuery.param (jquery-1.12.4.js:10095)
    at Function.ajax (jquery-1.12.4.js:9612)
    at HTMLFormElement.<anonymous> (main.js:102)
    at HTMLFormElement.dispatch (jquery-1.12.4.js:5226)
    at HTMLFormElement.elemData.handle (jquery-1.12.4.js:4878)

And line 102 of main.js corresponds to the ajax call when I try to upload the file

var event_form = $.ajax({
    url: 'ajax/addevent.php',
    method: 'POST',
    data: data,
    dataType: 'json',
    error: function (error){
      console.log(error);
    },
    success: function (json){
      console.log(json);
    },
    complete: function (jqXHR, textStatus) {
      console.log(`AJAX thinks login request was a ${textStatus}`);
    }
  });

If someone could tell me what I'm doing wrong that would be great!

Code

main.js

$(document).ready(function () {
$("form[name='event-form']").submit(function(e){
    e.preventDefault();

    var title = $(this).find("input[name='title']").val();
    var start_date = $(this).find("input[name='start_date']").val();
    var start_time = $(this).find("input[name='start_time']").val();
    var end_date = $(this).find("input[name='end_date']").val();
    var end_time = $(this).find("input[name='end_time']").val();
    var place = $(this).find("input[name='place']").val();
    var description = $(this).find("input[name='description']").val();
    var file = $(this).find("input[name='file']")[0].files[0];
    var data = {title: title, start_date: start_date, start_time: start_time,
                end_date: end_date, end_time: end_time, place: place,
                description: description, file: file};
    if(title && start_date && start_time){
      var event_form = $.ajax({
        url: 'ajax/addevent.php',
        method: 'POST',
        data: data,
        dataType: 'json',
        error: function (error){
          console.log(error);
        },
        success: function (json){
          console.log(json);
        },
        complete: function (jqXHR, textStatus) {
          console.log(`AJAX thinks login request was a ${textStatus}`);
        }
      });
    }
  });
});

event-form.php

<div id="addeventform"class="event-form form-screen pop-up">
  <button class="close-pop-up"><span class="icon-x"></span></button>
  <form name="event-form" method="post" enctype="multipart/form-data">
      <h1>Create Event</h1>
      <div class="form-content">
        <div class="box">
          <input type="file" name="file" id="file" class="inputfile" data-multiple-caption="{count} files selected" multiple />
          <label for="file">
            <svg xmlns="http://www.w3.org/2000/svg" width="20" height="17" viewBox="0 0 20 17">
              <path d="M10 0l-5.2 4.9h3.3v5.1h3.8v-5.1h3.3l-5.2-4.9zm9.3 11.5l-3.2-2.1h-2l3.4 2.6h-3.5c-.1 0-.2.1-.2.1l-.8 2.3h-6l-.8-2.2c-.1-.1-.1-.2-.2-.2h-3.6l3.4-2.6h-2l-3.2 2.1c-.4.3-.7 1-.6 1.5l.6 3.1c.1.5.7.9 1.2.9h16.3c.6 0 1.1-.4 1.3-.9l.6-3.1c.1-.5-.2-1.2-.7-1.5z" /> </svg> <span>Choose a file&hellip;</span> </label>
        </div>
        <input type="text" name="title" placeholder="Title*" required>
        <input type="text" name="start_date" class="date" placeholder="Start Date*" required>
        <input type="text" name="start_time" class="timepicker" placeholder="Start Time*" required>
        <h1 class="time-label">to</h1>
        <input type="text" name="end_date" class="date" placeholder="End Date">
        <input type="text" name="end_time" class="timepicker" placeholder="End Time">
        <input type="text" name="place" placeholder="Place">
        <input type="text" name="description" placeholder="Description">
      </div>
      <button type="submit" class="submit" name="submit" value="submit">Add Event</button>
  </form>
</div>

addevent.php

<?php
session_start();
require_once '../config-db.php';

//Set up SQL
$query = "INSERT INTO events (title, start_date, start_time, end_date, end_time, place, description)
          VALUES (:title, :start_date, :start_time, :end_date, :end_time, :place, :description)";
$fields = array('title', 'start_date', 'start_time', 'end_date', 'end_time', 'place', 'description');
$stmt = $db->prepare($query);

//Set up return
$error['error'] = array();

//N2SELF: N2Do DATA VALIDATION

if(!empty($_FILES['file'])){
  $image=$_FILES['file'];
  $file_name=$_FILES['file']['name'];
  $image_tmp =$_FILES['file']['tmp_name'];
  if($_FILES['file']['error'] === 0){
    $file_path = "images/";
    $move_successfully = move_uploaded_file( $image_tmp, $file_path.$file_name);
    if(!$move_successfully){
      $error['error'][] = "$image_tmp was not moved successfully";
    }
    $_SESSION['photos'][] = $file_name;
    $error['error'][] = "$image_tmp was moved successfully";
  }
}

foreach($fields as $field){
  if($field === 'title' || $field === 'start_date' || $field === 'start_time'){
    if(empty($_POST[$field])){
      $error['error'][] = "No required field: $field";
    }
  }

  if($field === 'title'){
    $value = (!empty($_POST[$field])) ? $_POST[$field] : "Untitled";
  }elseif($field === 'start_date'){
    $value = (!empty($_POST[$field])) ? $_POST[$field] : "NO DATE";
  }
  elseif($field === 'start_time'){
    $value = (!empty($_POST[$field])) ? $_POST[$field] : "NO TIME";
  }else{
    $value = (!empty($_POST[$field])) ? $_POST[$field] : NULL;
  }

  $parameter = ":$field";
  $paramToValues[$parameter] = $value;
}
$executed = $stmt->execute($paramToValues);
if(!$executed){
  $error['error'][] = "SQL query $query not executed";
  echo json_encode($error);
  exit();
}

foreach($fields as $field){
  $error['fields'][] = $_POST[$field];
}
echo json_encode($error);
?>

Update

main.js

$("form[name='add-event-form']").submit(function(e){
    e.preventDefault();
    var title = $(this).find("input[name='title']").val();
    var start_date = $(this).find("input[name='start_date']").val();
    var start_time = $(this).find("input[name='start_time']").val();
    var end_date = $(this).find("input[name='end_date']").val();
    var end_time = $(this).find("input[name='end_time']").val();
    var place = $(this).find("input[name='place']").val();
    var description = $(this).find("input[name='description']").val();
    var file = $(this).find("input[name='file']")[0].files[0];
    var fileData = new FormData();
    fileData.append('file', file);
    var data = {title: title, start_date: start_date, start_time: start_time,
                end_date: end_date, end_time: end_time, place: place,
                description: description, file: fileData};
    console.log(data);
    if(title && start_date && start_time){
      var event_form = $.ajax({
        url: 'ajax/addevent.php',
        method: 'POST',
        processData: false,
        contentType: false,
        data: data,
        dataType: 'json',
        error: function (error){
          console.log(error);
        },
        success: function (json){
          console.log(json);
        },
        complete: function (jqXHR, textStatus) {
          console.log(`AJAX thinks login request was a ${textStatus}`);
        }
      });
    }

For some reason when I pass in my object using the suggestions I'm getting back all the errors I encoded in my addevent.php namely:

"No required field: title"
"No required field: start_date"
"No required field: start_time"
14wml
  • 4,048
  • 11
  • 49
  • 97
  • can you do `console.log()` in `main.js` & check there is no jqyery object in that – Agam Banga May 06 '17 at 17:13
  • The issue is because you're trying to put binary data from `$(this).find("input[name='file']")[0].files[0]` in to an object which jQuery will then serialise as a string. To fix the problem, use a `FormData` object to upload the binary data correctly. See the duplicate question for more details – Rory McCrossan May 06 '17 at 17:19
  • @RoryMcCrossan could you provide me the code on how I can add the `FormData` to my json object I'm sending to `addevent.php`? b/c I'm not just sending a `FormData` to `addevent.php`, I'm also send the other form fields – 14wml May 06 '17 at 17:25
  • It's all in the other question I linked to. Note that you don't put the `FormData` in an object, you just send the `FormData` directly – Rory McCrossan May 06 '17 at 17:26
  • @15ongm I was gonna answer it before it got closed but add `contentType` and `processData` to your ajax call. – Junius L May 06 '17 at 17:26
  • @RoryMcCrossan could you not mark it as a duplicate so julekgwa can respond? This would be really helpful to me even though I know you think this is the same question as the other post. Looking at the post, they're sending formData. I'm sending my own custom object. – 14wml May 06 '17 at 17:28
  • @15ongm there's no need, the answer is there for you, just scroll down to the ajax call and copy `contentType: false, processData: false,` and paste them in your ajax call. – Junius L May 06 '17 at 17:32
  • @julekgwa yes I've done that. and now it's not reading my other form inputs that I pass in it... So I think either `processData: false` or `contentType: false` is messing with my sending of the other data in my `data` object – 14wml May 06 '17 at 17:36
  • php or javascript? – Junius L May 06 '17 at 17:36
  • like the `php` is not getting the information that the `javascript` sends – 14wml May 06 '17 at 17:37
  • I'm going to update my post with what I have right now in `main.js` – 14wml May 06 '17 at 17:38
  • I think you'll have to ask another question and provide the code for us to see. – Junius L May 06 '17 at 17:39
  • @15ongm the problem is we can't answer this question as it was closed. – Junius L May 06 '17 at 17:44
  • @julekgwa okay i've posted a new question here http://stackoverflow.com/questions/43823584/form-data-not-going-through-when-try-to-send-formdata-using-ajax please do take a look if you can – 14wml May 06 '17 at 17:46

0 Answers0