I have a model Picture where I take a photo with webcam and save it. I upload the images with carrierwave, and generate the image with the gem carrrierwave-data-uri The image is sent by ajax
the function on my PicturesController.rb is:
def upload_image
photo = params[:picture][:photo]
#picture = Picture.new(picture_params)
#picture.user_id = current_user.id
#picture.photo = photo
#picture.save
end
private
def set_picture
#picture = Picture.find(params[:id])
end
def picture_params
params.require(:picture).permit(:photo, :comment, :user_id )
end
end
My Ajax
function save_photo() {
Webcam.snap( function(data_uri) {
$.ajax({
type: 'POST',
url: '/pictures/upload',
async: true,
data: { picture: {photo: data_uri} }
})
.done(function () {
console.log(photo);
});
Webcam.reset();
} );
}
When I send the image, it is registered on database, but not the image. I getting the console error:
Unpermitted parameter: image
But if I add the parameter :image on my strong parameters, I get the Completed 500 Internal Server Error
The data uri is printed on my console, but I can't put it in a image variable
Thanks by help!
You get 500 Internal Server Error when permitting image because you don't have an image attribute in the model. You have photo instead, so you should use it as the parameter to send data_uri in the ajax method.
Change image in the AJAX call to photo:
data: { picture: { photo: data_uri } }
Also make change in your controller method like this:
def upload_image
#picture = Picture.new(picture_params)
#picture.user_id = current_user.id
#picture.save
end
Related
I have a html page that allows a user to take a screenshot from their camera.
This screenshot is then rendered in the page with the function from main.js down below.
If i do console.log(image) i get image tag with a src to a blob:http that has the image.
Now for the fun part. I want to post this image to my api in django rest framework.
Basically how do i go from a blob image to a post request to the api?
I tried using $.ajax but I dont know how to format the "blob data" to be accepted for the "data:" parameter field in ajax.
Note also that i'm not using forms in the html, when i do that the html page gets refreshed as soon as i take a screenshot so the image does not stay on the page..
If I have to use forms in order to make this work, please let me know and I will try another approach.
main.js
async function grabFrame() {
const img = await imageCapture.grabFrame();
const url = URL.createObjectURL(await imageCapture.takePhoto());
document.querySelector("img").src = url
#id_image is where the screenshot is located
const image = document.getElementById('id_image')
console.log(image)
index.html
<button onclick="grabFrame()">Grab Frame</button>
<img id="id_image" style="width:320px; height:240px"/>
models.py
class Image(models.Model):
image = models.ImageField(upload_to='media/')
serializer.py
class ScreenshotCreateSerializer(ModelSerializer):
class Meta:
model = Image
fields = [
'image'
]
views.py
class SaveScreenshot(CreateAPIView):
serializer_class = ScreenshotCreateSerializer
permission_classes = [AllowAny]
def home_view(request):
return render(request, 'index.html', {})
what i tried in the main.js
// $.ajax({
// url: "/api/save_screenshot",
// type: "POST",
// processData: false,
// mimeType: "multipart/form-data",
// contentType: false,
// data: blob data?,
// success: function (data) {
// alert("Screenshot saved successfully!");
// },
// error: function (e) {
// console.log(e);
// }
// }).done(function(o) {
// });
I'm trying to create a jackpot betting site (just as a challenge). I have a method in my controller to update the pot when a user adds money to the pot. I display the pot total on the homepage and would like to update it with Ajax as soon as someone adds money to the pot. I'm using the gon gem to pass variables such as the pot total from my controller to my javascript. It works when the page is reloaded but not when the update method is called with ajax.
Heres my PagesController:
def home
#jackpot = Jackpot.last
gon.pot = #jackpot.pot
end
JackpotsController:
def update
#jackpot = Jackpot.find(params[:id])
if params.has_key?(:amount)
#jackpot.update(pot: #jackpot.pot + params[:amount].to_f)
gon.pot = #jackpot.pot
end
respond_to do |format|
format.js
end
end
Javascript: (In the url the :id is hardcoded for now)
$("#bet-btn").click(function() {
$.ajax({
type: "POST",
url: "/jackpot/update/21",
datatype: "json",
success: function() {
console.log("Pot size: " + gon.pot);
updatePot();
},
error: function() {
console.log("error")
}
});
});
This updates the donut progress bar for the pot
function updatePot() {
updateDonutChart('#jackpot-donut', gon.pot , true);
}
Button to place bet: (amount also hardcoded)
<%= link_to "Place Bet", update_pot_path(#jackpot, :amount =>
0.1), method: :post,:remote => true, id: "bet-btn", class: "btn btn-info btn-lg" %>
I'm pretty new to rails and especially javascript/ajax so any help would be appreciated. Thanks!
In the controller, simply respond to JSON:
respond_to do |format|
format.json { render json: { pot: #jackpot.pot } }
end
Specify the dataType when posting with $.ajax. Notice that the new data is bieng passed to the success function, so it's not gon.pot, but data.pot.
$.ajax({
dataType: "json",
url: url,
data: data,
success: function(data) {
console.log('pot', data.pot);
}
});
I'm trying to upload a data_uri image from my webcam by ajax with rails uising this gem
For that I have a custom function on my PicturesController.rb:
def upload_image
data_uri = params[:data_uri]
#picture = Picture.new(picture_params)
#picture.user_id = current_user.id
if data_uri
#picture.photo = data_uri
end
#picture.save
end
and the javascript on my page:
function save_photo() {
Webcam.snap( function(data_uri) {
$.ajax({
type: 'POST',
url: '/pictures/upload',
async: true,
data: { data_uri: data_uri }
})
.done(function () {
console.log(data_uri);
});
// shut down camera, stop capturing
Webcam.reset();
} );
}
I'm also use the gem rack-cors to solve cross domain problems.
My route.rb
resources :pictures do
collection do
post 'upload', :action => :upload_image
end
end
But when I call the ajax function I getting the 400 (Bad Request)
The console show the error:
ActionController::ParameterMissing - param is missing or the value is empty: picture:
Has anyone had this problem before?
Thanks!
In AJAX I write:
$.ajax({
URL: '/new_avatar',
type: 'POST',
data: { username: 'alizade' },
success: function(response){
alert(response);
},
})
Route.rb:
post '/new_avatar' => 'avatars#new_avatar'
Avatar.rb model:
self.new_avatar(username)
Avatar.where(username: username).select('avatar').last
end
Avatars_Controller:
def new_avatar
#username = params[:username]
#result = Avatar.new_avatar(#username)
end
So, how can send #result to AJAX response function and alert the database selection result?
Assuming you need only response from this service, you can use following way to get the result.
def new_avatar
#username = params[:username]
render :json => Avatar.new_avatar(#username)
end
you need to use render :text in your controller method
def new_avatar
#username = params[:username]
#result = Avatar.new_avatar(#username)
render :text => "#{#username} has this result:- #{#result.inspect}"
end
I would like to post the result of an ajax request back to the same page that it was requested from. Here are the interacting parts:
AJAX in Jquery
var ids = 1
$(document).ready(function(){
$('#showbtn').on('click', function() {
$.ajax({
url: "http://localhost:3000/teamplayers.json",
data: {'resolution':ids},
type:"post",
dataType: "json",
cache: true,
success:function(){
$('#test3').val(1);
alert("test 3");
},
error: function(error) {
alert("Failed " + console.log(error) + " " + error)
}
});
});
});
This is supposed to set a variable here:
Teamplayer Controller
# GET /teamplayers
# GET /teamplayers.json
def index
#teamplayers = Teamplayer.all
#fteams = Fteam.all
#teamplayer2 = 1
tid = params[:resolution] <-It should set here per the data section above
#ids = tid
end
unfortunately it calls this section of the same controller
# POST /teamplayers
# POST /teamplayers.json
def create
#teamplayer = Teamplayer.new(teamplayer_params)
respond_to do |format|
if #teamplayer.save
format.html { redirect_to #teamplayer, notice: 'Teamplayer was successfully created.' }
format.json { render action: 'show', status: :created, location: #teamplayer }
else
format.html { render action: 'new' }
format.json { render json: #teamplayer.errors, status: :unprocessable_entity }
end
end
end
So what do I do to make it post to the same page.
You are POSTing the ajax, which means the create action will be hit, not the index action. You should be able to see this in your server log output when you hit the page.
If you want to hit the index action, you need to do an GET ajax request with the resolution data set so you can get the data you want.
Additionally, you probably maybe don't want to cache this ajax request if it is actually dynamic data, but it is up to you.
Edit from comments:
You need to add your parameter as a query string for a GET, not as generic "data".
Try something like this:
$.ajax({
url: "http://localhost:3000/teamplayers.json?resolution="+ids,
type:"GET",
dataType: "json",
success:function(){
$('#test3').val(1);
alert("test 3");
},
error: function(error) {
alert("Failed " + console.log(error) + " " + error)
}
});
});
Another edit from comments:
# GET /teamplayers
# GET /teamplayers.json
def index
#teamplayers = Teamplayer.all
#fteams = Fteam.all
#teamplayer2 = 1
tid = params.fetch(:resolution) { 0 } # make sure we got something
#ids = tid.to_i # coerce string param to integer
end