skip to Main Content

I have an ajax call that is inside a function (pushed to the end of the page) in a view file. On ajax success, I need to perform some front-end manipulation using variables from the returned data.

The issue is that the page is not loading due to an error that the variables are undefined, but I am not sure why they would even be needed to be defined until the function is called.

This is the success function:

success: function (data, xhr) {
    var indexAttachment = $('#attachments').attr('data-attachment');
    if(xhr === 'success' && data['id'] !== null) {
        var id = data['id'];
        var fileName = data['fileName'];
        if(indexAttachment === null) {
            var indexAttachment = 0;
            $('#NoAttachments').remove();
        }
        indexAttachment++;
        var html = `<x-attachment id="${id}" index="${indexAttachment}" fileName="${fileName}" />`;
        $(html).hide().appendTo("#attachments").fadeIn(250);
    }
}

The issue is with:

var html = `<x-attachment id="${id}" index="${indexAttachment}" fileName="${fileName}" />`;

I have also tried not using the component as well as using variable concatenation like this and it encodes the undefined values at page load:

var html = '<x-attachment id="'+id+'" index="'+indexAttachment+'" fileName="'+fileName+'" />

To eliminate it being a component, I tried an element directly:

var html = `<span data-attachment="${id}"><a href="{{ route('document.download', [${id},preg_replace('/[^w-.]/', '-', basename(${fileName})) ]) }}" name="{{ preg_replace('/[^w-.]/', '-', basename(${fileName})) }}" id="document_${index}">${fileName}</a></span>`;

Which results in an error:
Undefined constant "id"

Here is the complete ajax call inside the function:

var attachment = new FormData('#form);
$.ajax({
  async: false,
  type: "post",
  url: "{{ route('upload.attachment') }}",
  cache: false,
  processData: false,
  contentType: false,
  data: attachment,
  success: function (data, xhr) {
  var indexAttachment = $('#attachments').attr('data-attachment');
  if(xhr === 'success' && data['id'] !== null) {
    var id = data['id'];
    var fileName = data['fileName'];
    if(indexAttachment === null) {
      var indexAttachment = 0;
      $('#NoAttachments').remove();
    }
    indexAttachment++;
    var html = `<x-attachment id="${id}" index="${indexAttachment}" fileName="${fileName}" />`;
    $(html).hide().appendTo("#attachments").fadeIn(250);
  }
});

I have another ajax call in the same function with success using another component with variables and it works as expected.

var html = `<x-note name="${createdBy}" text="${text}" index="${index}" />`;

I think it’s worth noting that the ajax call is working as expected.

Thank you

2

Answers


  1. Chosen as BEST ANSWER

    After some tinkering, I believe I found the issue. It appears that the {{ route }} command is trying to render and is looking for the values. Replacing route('document.download') with the path instead of the route name seems to have fixed the error, but the values are still not defined.

    This is what I used instead in the component:

    <a href="documents/{{$id}}/download/{{ preg_replace('/[^w-.]/', '-', basename($fileName)) }}" name="{{ preg_replace('/[^w-.]/', '-', basename($fileName)) }} id="document_{{ $index }}">{{ $fileName }}</a>
    

    I may have to use a partial view to get the values populated.


  2. Your ajax seems to be written wrong. You have a curly brace between the data and success properties that could be messing everything up.

    var attachment = new FormData('#form');
    $.ajax({
        async: false,
        type: "post",
        url: "{{ route('upload.attachment') }}",
        cache: false,
        processData: false,
        contentType: false,
        data: attachment,
        success: function (data, xhr) {
            var indexAttachment = $('#attachments').attr('data-attachment');
            if(xhr === 'success' && data['id'] !== null) {
                var id = data['id'];
                var fileName = data['fileName'];
                if(indexAttachment === null) {
                    var indexAttachment = 0;
                    $('#NoAttachments').remove();
                }
                indexAttachment++;
                var html = `<x-attachment id="${id}" index="${indexAttachment}" fileName="${fileName}" />`;
                $(html).hide().appendTo("#attachments").fadeIn(250);
            }
        }
    });
    

    I don’t think <x-attachment> would work though. It’s a blade component that the blade compiler needs to evaluate and render before the page loads. It won’t get re-evaluated when your ajax finishes with new values.

    Copying the entire component’s definition doesn’t seem like a good idea either, since you have a lot of php functions in it (preg_replace, basename) that again, get evaluated before the page loads

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search