Trying to upload an image and getting an error

I kept getting this error :

attempt to index global 'button' (a nil value)

I had two buttons with the same exact values so I thought that was the problem . When I removed one I was able to click the button and select a photo . When I selected the photo , I went back to the profile.lua file and nothing happened . Then I clicked the profile.lua tab and I got this error :

profile.lua:116 attempt to call method 'addEventListener' (a nil value) 

What’s wrong with it ?

local composer = require( "composer" ) local scene = composer.newScene() local widget = require("widget") -- forward declare the text fields local json = require("json") local button local MultipartFormData = require("class\_MultipartFormData") local userName = composer.getVariable( "username" ) local function networkListener( event ) if ( event.isError ) then local alert = native.showAlert( "Error Loading .", "Check your internet connection .", { "Try again" } ) end end -- Selection completion listener local function onComplete( event ) local photo = event.target if photo then print( "photo w,h = " .. photo.width .. "," .. photo.height ) local multipart = MultipartFormData.new() local path=system.pathForFile( "bg1.png", system.TemporaryDirectory ) multipart:addFile("Image", path, "images/uploads", userName .. ".jpg") local params = {} params.body = multipart:getBody() params.headers = multipart:getHeaders() -- Headers not valid until getBody() is called. network.request("http://hash.host22.com/upload.php", "POST", networkListener, params) end end local function pickPhoto( event ) media.selectPhoto( { mediaSource = media.SavedPhotosAlbum, listener = onComplete, origin = button.contentBounds, permittedArrowDirections = { "right" }, destination = { baseDir=system.TemporaryDirectory, filename= userName .. ".jpg" } }) end button = widget.newButton( { shape = "roundedRect", left = 70, top = 350, id = "pfp", label = "Upload picture", onEvent = pickPhoto, fillColor = { default={ 1, 0.2, 0.5, 0.7 }, over={ 1, 0.2, 0.5, 1 } }, labelColor = { default={ 2, 4, 1.5 }, over={ 2, 5, 1.5, 2.2 } } } ) function scene:create(event) local screenGroup = self.view local background = display.newImageRect("insta.jpg",display.contentWidth,display.contentHeight) background.x = display.contentCenterX background.y = display.contentCenterY screenGroup:insert(background) local passedInParams = event.params --\<------ important. This is how you get the passed values local userNameText = display.newText(userName, 160, 200, native.systemFont, 30 ) userNameText:setFillColor( 1, 0, 0 ) screenGroup:insert(userNameText) end local tabButtons = { { label = "#News Feed", width = 52, height = 10, id = "newsfeed", size = 16, onPress = function() composer.gotoScene("newsfeed"); end, selected = true }, { label = "#Profile", size = 16, id = "profile", onPress = function() composer.gotoScene("profile"); end, selected = true } } -- Create the widget local tabBar = widget.newTabBar( { top = display.contentHeight -52, width = display.contentWidth, buttons = tabButtons, } ) function scene:show(event) local phase = event.phase if ( phase == "will" ) then print("Phase started") button:addEventListener( "tap", pickPhoto ) elseif ( phase == "did" ) then print("phase on login") end composer.removeScene( "login" ) end scene:addEventListener( "show" ) function scene:hide(event) local phase = event.phase if ( phase == "will" ) then print("Phase started") button:removeEventListener( "tap", pickPhoto ) display.remove(button) elseif ( phase == "did" ) then print("phase on login") end end function scene:destroy(event) end scene:addEventListener("create", scene) scene:addEventListener("show", scene) scene:addEventListener("hide", scene) scene:addEventListener("destroy", scene) return scene

“button”, “tabBar” and “tabButtons” should all be inside scene:create().  “button” and “tabBar” should be added to your scene group.

A button widget does not use a :addEventListener() or does it need a :removeEventListener() that’s handled internally by the widget. If you add the button to your scene’s view group, you won’t need to delete it in scene:hide()

Ok so … Where does the image go ? I have a images/uploads path but there is nothing there . How do I make it go there ?

Also is it only limited to jpg images ? If so can I change it to any picture ? GIF PNG etc ?

This block of code:

 media.selectPhoto( { mediaSource = media.SavedPhotosAlbum, listener = onComplete, origin = button.contentBounds, permittedArrowDirections = { "right" }, destination = { baseDir=system.TemporaryDirectory, filename= userName .. ".jpg" } })

The destination = { baseDir=system.TemporaryDirectory, filename= userName … “.jpg” } tells the photo album dialog to copy the image to system.TemporaryDirectory and name it after the user’s userName and make it a jpeg file. When this completes and if the user **did not** cancel the dialog (you need to handle that condition) then the photo will be in a place where your upload code will find it. But until you can tap your button and select and image and say to use it, you won’t be able to upload it.

I don’t know of a way to tell you how to determine if an image is a GIF, JPEG or PNG, so I’m going to say it’s limited to JPEG and PNG.

Rob

Hello . I;m still having this problem . 

local function networkListener( event ) if ( event.isError ) then local alert = native.showAlert( "Error Loading .", "Check your internet connection .", { "Try again" } ) end end -- Selection completion listener local function onComplete( event ) local photo = event.target if photo then print( "photo w,h = " .. photo.width .. "," .. photo.height ) local multipart = MultipartFormData.new() local path=system.pathForFile( "bg1.png", system.TemporaryDirectory ) multipart:addFile("Image", path, "images/uploads", userName .. ".jpg") local params = {} params.body = multipart:getBody() params.headers = multipart:getHeaders() -- Headers not valid until getBody() is called. network.request("http://hash.host22.com/upload.php", "POST", networkListener, params) end end local function pickPhoto( event ) media.selectPhoto( { mediaSource = media.SavedPhotosAlbum, listener = onComplete, origin = button.contentBounds, permittedArrowDirections = { "right" }, destination = { baseDir=system.TemporaryDirectory, filename= userName .. ".jpg" } }) end

That’s my current code I don’t know what to do i’m stuck 

I don’t know what the multipart:add() is expecting, but this doesn’t look right to me:

 local path=system.pathForFile( "bg1.png", system.TemporaryDirectory ) multipart:addFile("Image", path, "images/uploads", userName .. ".jpg")

What is bg1.png? How does it get to system.TemporaryDirectory?  I think you probably want:

 local path=system.pathForFile( userName .. ".jpg", system.TemporaryDirectory ) multipart:addFile("Image", path, "images/uploads", userName .. ".jpg")

or something similar.

Rob

bg1.png is an image . The code you gave, is that to store the images in there ?

In your call to media.selectPhoto() you are saying to save a file named after the user’s userName as a .jpg file and put it in system.TemporaryDirectory:

destination = { baseDir=system.TemporaryDirectory, filename= userName .. ".jpg" } 

I don’t see where your app is generating a file named bg1.png, so it doesn’t make sense to me that would be a file you want to upload. Now I don’t have the source of documentation for the “multipart” library you are using. So I’m guessing at what parameters are needed but I expect you need an input file name and a file name to name it on the server.  I would also expect that on your server you want the person’s profile image named after their username as well.

So you need to figure out what bg1.png is and why you’re using it there or understand that you probably copy/pasted that from somewhere and you need to use the actual filename of the image selected by the user which is userName … “.jpg”.

Rob

My goal is to make the user put any picture as their profile picture not bg1.png

Did you try my suggestion?

I don’t even see bg1.png anymore . I just want to store the users photos to the system temporary file and then let them pick one as the profile pic.

I’m still having problems here . I have the app on my phone. When I click on the upload button I go to my gallery and select a picture . When I select the picture I go right back to the profile.lua screen and the image doesn’t get saved . Nothing happens .

 button = widget.newButton( { shape = "roundedRect", left = 70, top = 350, id = "pfp", label = "Upload picture", onEvent = pickPhoto, fillColor = { default={ 1, 0.2, 0.5, 0.7 }, over={ 1, 0.2, 0.5, 1 } }, labelColor = { default={ 2, 4, 1.5 }, over={ 2, 5, 1.5, 2.2 } } } ) screenGroup:insert(button)

local MultipartFormData = require("class\_MultipartFormData") -- Selection completion listener local function onComplete( event ) local photo = event.target if photo then print( "photo w,h = " .. photo.width .. "," .. photo.height ) local multipart = MultipartFormData.new() local path=system.pathForFile( userName .. ".jpg", system.TemporaryDirectory ) multipart:addFile("Image", path, "images/uploads", userName .. ".jpg") local params = {} params.body = multipart:getBody() params.headers = multipart:getHeaders() -- Headers not valid until getBody() is called. network.request("http://hash.host22.com/upload.php", "POST", networkListener, params) end end local function pickPhoto( event ) media.selectPhoto( { mediaSource = media.SavedPhotosAlbum, listener = onComplete, origin = button.contentBounds, permittedArrowDirections = { "right" }, destination = { baseDir=system.TemporaryDirectory, filename= userName .. ".jpg" } }) end

Again, I don’t know anything about the library you are using for the multipart mime extension. I can’t verify that you are passing the right parameters to the function.  Secondly, I don’t know the code of your upload.php script and if it works with how you are attempting to send the file.

Where did you get the multipart mime code?

Can you share your upload.php script?

Rob

upload.php:

ini\_set('display\_errors', 1); ini\_set('display\_startup\_errors', 1); error\_reporting(E\_ALL); $servername = "localhost"; $username = "id1662780\_btisson13"; $password = "bigman23"; $database = "id1662780\_hash"; $con = new mysqli($servername, $username, $password, $database); if($con == true) { } // Check connection if ($con-\>connect\_error) { die("Connection failed: " . $con-\>connect\_error); } include("auth\_login.php"); $target\_dir = "images/uploads/"; $target\_file = $target\_dir . basename($\_FILES["fileToUpload"]["name"]); $uploadOk = 1; $imageFileType = pathinfo($target\_file,PATHINFO\_EXTENSION); // Check if image file is a actual image or fake image if(isset($\_POST["change"])) { move\_uploaded\_file($\_FILES["fileToUpload"]["tmp\_name"], $target\_file); if($check !== false) { echo "\<a href = profile.php\> Profile pciture has been changed \</a\>" . $check["mime"] . "."; $uploadOk = 1; } else { echo "File is not an image."; $uploadOk = 0; } }

I don’t know where I got that code from. I think it was from an example 

Do you know of an alternative way I can do this ?

In my opinion, I understood how to fix this.

Thank you for the information and your example.

As soon as I manage, I will show my results.

regards bestazy

Cheer. :slight_smile:

I have this code and it’s not working . When I click on the button and it takes me to my gallery and I click on the picture I want to upload, I just go straight back into the profile.lua page and nothings happens . 

local MultipartFormData = require("class\_MultipartFormData") local multipart = MultipartFormData.new() local path=system.pathForFile( "image.jpg", system.TemporaryDirectory ) multipart:addFile("Image", path, "image/jpg", "image.jpg") local params = {} params.body = multipart:getBody() params.headers = multipart:getHeaders() -- Headers not valid until getBody() is called. network.request("http://hash.x10host.com/cgi-bin/hash/upload.php", "POST", listener, params) local image local mime = require "mime" local bkgd = display.newRect( 0, 0, display.contentWidth, display.contentHeight ) bkgd:setFillColor( 0, 0, 0 ) local myRoundedRect = display.newRoundedRect(10, 50, 80, 50, 12) myRoundedRect.strokeWidth = 3 myRoundedRect:setFillColor(140, 140, 140) myRoundedRect:setStrokeColor(180, 180, 180) local sessionComplete = function(event) image = event.target print( "Camera ", ( image and "returned an image" ) or "session was cancelled" ) print( "event name: " .. event.name ) print( "target: " .. tostring( image ) ) if image then -- center image on screen image.x = display.contentWidth/2 image.y = 59 local w = image.width local h = image.height image.xScale = 0.3 image.yScale = 0.3 print( "w,h = ".. w .."," .. h ) end end local listener = function( event ) if media.hasSource( media.Camera ) then media.show( media.Camera, sessionComplete ) else native.showAlert("Corona", "Camera not found.") end return true end myRoundedRect:addEventListener( "tap", listener ) local myRoundedRect1 = display.newRoundedRect(10, 400, 150, 50, 12) myRoundedRect1.strokeWidth = 3 myRoundedRect1:setFillColor(140, 140, 140) myRoundedRect1:setStrokeColor(180, 180, 180) local Name = "Imagename" function uploadBinary ( filename, url, onComplete ) -- local path = system.pathForFile( filename ) -- local fileHandle = io.open( path, "rb" ) -- if fileHandle then if image then local params = { body = "image\_file=" .. mime.b64(tostring( image )) .. "&image\_filename="..Name } -- io.close( fileHandle ) local function networkListener ( event ) if (onComplete) then onComplete(event); end return true; end network.request( url, "POST", networkListener, params) end end local function networkListener( event ) if ( event.isError ) then print( "Network error!") else -- print ( "RESPONSE: " .. event.response) print ("Working") end end local function Upload () uploadBinary ( image, "http://www.test1.bugs3.com/Corona.php", networkListener) end myRoundedRect1:addEventListener( "tap", Upload )

upload.php:

$username = $\_SESSION['username']; if(isset($\_FILES['image'])){ $errors= array(); $file\_name = $\_FILES['image']['name']; $file\_size = $\_FILES['image']['size']; $file\_tmp = $\_FILES['image']['tmp\_name']; $file\_type = $\_FILES['image']['type']; $file\_ext=strtolower(end(explode('.',$\_FILES['image']['name']))); $extensions= array("jpeg","jpg","png"); if(in\_array($file\_ext,$extensions)=== false){ $errors[]="extension not allowed, please choose a JPEG or PNG file."; } if($file\_size \> 2097152) { $errors[]='File size must be 2 MB'; } if(empty($errors)==true) { move\_uploaded\_file($file\_tmp,"uploads/".$file\_name); $store=mysqli\_query($conn,"UPDATE users SET userPic='$userPic' WHERE username='$username'"); mysqli\_query($conn,$store); echo "Success"; }else{ print\_r($errors); echo"it failed"; } }

I am connected to the internet but I just didn’t post that code above 

@Rob , can I just get a step by step of what to do to upload my image to the database ? Like what folder i’d have to upload it in etc . Thanks