How to download a file on client after an Ajax request

1.2k views Asked by At

I have a django app where users can save their contacts. I am not building a flow to allow users to download their contacts locally.

To do so, I built a CTA ("download") that if clicked

  1. Gets the id of the contact selected
  2. Triggers an Ajax request to my views
  3. In the view I get the contact id, retrieve the data from my DB and create a VCF card out of it. (A contact card - basically a text file)

Now I would like to have such file downloaded on the client's machine but I don't know how to do it.

I managed to do it if I redirect to a new url where the view does exactly what my view below does, I want to allow users to download the file without being redirected to a new page. Also, trying to avoid storing the contact ids in the URL.

That's why I am trying to use ajax but I think that's creating problems because and Ajax request waits JsonReponse from the view.

I tried both a GET or POST but it's not working.

This is my view currently:

        def get(self, request, *args, **kwargs):

        #Get the ids
        ids = request.GET.getlist('contact_ids[]')

        # Get contqacts associated with ids
        contacts = Contact.objects.filter(id__in=ids)
        
        # Transform contacts into long text
        text = Vcard().GroupVcards(contacts)

        #Create file on the fly and attach it to the response (is this correct actually?)
        response = HttpResponse(content_type='text/plain')
        response['Content-Disposition'] = 'attachment;filename=ven.vcf'
        response.writelines(text)

        #return 
        return response

This is the Jquery triggering the ajax


    $('.Vcard').on('click', function(e) {
        let id = $(this).data('contact_id')
       

        $.ajax({
            type: "GET",
            url: Urls['action:DownloadContact'](),
            data: {
                csrfmiddlewaretoken: csrftoken,
                'contact_ids': [id],
            },
            error: function(response){
                console.log(response)
                console.log('error')

            },
            success: function(response) {
                console.log(response)
                console.log('success')
            }
          });
    })




0

There are 0 answers