Roberto Pezzali Roberto Pezzali - 1 month ago 22
jQuery Question

Rails ajax with POST function: why template missing?

I'm completing an avatar upload and crop using ajax submit.

I'm sending via ajax the base64 image and then I convert my image for carrierwave.

Everything works fine, except for the ajax response: Template missing.

This is my ajax call:

$.ajax({
type: "post",
dataType: "json",
url: "/profile/update_avatar",
data: { image: canvas.toDataURL() }
})
.done(function(data) {

// You can pull the image URL using data.url, e.g.:
$('.user-image').html('<img src="'+data.url+'" />');

});


And this is my controller:

def update_avatar
respond_to do |format|
if current_user.update_cropped_avatar(params[:image])
format.js
format.html { render :nothing => true, :notice => 'Update SUCCESSFUL!' }
else
format.html { render :action => "edit" }
format.json { render :json => current_user.errors, :status => :unprocessable_entity }
end
end


end

I don't need to render template... but the error is:

Missing template profiles/update_avatar, application/update_avatar with {:locale=>[:it], :formats=>[:js, :html], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :haml]}.


Why?

Answer

The problem will be your use of:

respond_to do |format|
    format.js

I know you sent JSON to Rails, but it seems you're only processing a standard script dataType when your avatar is sent correctly. Your use of format.js basically causes rails to look for action_name.js.erb in your views folder - hence your template error

There are numerous ways to fix this, including:

respond_to do |format|
    format.js { render nothing: true } 

Fix

After talking with Roberto in chat, here's what worked for him:

def update_avatar 
    respond_to do |format| 
        if current_user.update_cropped_avatar(params[:image]) 
            format.json { render :json => current_user.profile.avatar_url, :status => 200 } 
            format.html { render :nothing => true, :notice => 'Update SUCCESSFUL!' } 
        else 
            format.html { render :action => "edit" } 
            format.json { render :json => current_user.errors, :status => :unprocessable_entity } 
        end 
    end 
end