Files

The general reference to Communication explains where the different values can be used. gox.File represents a file with name, MIME type, size and content.

GOX uses it to receive files from JavaScript and to deliver them through Pages, Actions and WebSocket.


Equivalence

JavaScriptGoAvailability
Filegox.FileActions and WebSocket receive or send a file
File[], FileList[]gox.FileActions and WebSocket receive or send several files
HTTP responsegox.FilePages return a file

A Page Can't Return []gox.File. File collections are used in Actions and WebSocket.


Create a file

gox.NewFile() creates a file from a route or a io.Reader.

From a route

gox
file, err := gox.NewFile(gox.FileConfig{
    Path: "documents/report.pdf",
})

GOX uses the file name and deducts its MIME type from the extension.

From content

gox
file, err := gox.NewFile(gox.FileConfig{
    Name:    "report.txt",
    Type:    "text/plain",
    Content: strings.NewReader("Report for George"),
})

A source should be provided exactly: Path or Content.

Name is mandatory when used Content. Type is optional and, if omitted, GOX tries to deduct it from the name.


File information

gox.File sets out the main information by means of methods:

gox
name := file.Name()
contentType := file.ContentType()
size := file.Size()

It can also be obtained at once:

gox
info := file.Info()

println(info.Name)
println(info.ContentType)
println(info.Size)

The content is opened by Open():

gox
reader, err := file.Open()
if err != nil {
    ...
}
defer reader.Close()

Receive a file

An Action can receive a File directly as gox.File.

gox
func Upload(file gox.File) gox.Action {
    println(file.Name(), file.ContentType(), file.Size())
    return true
}
js
const [result, err] = await Actions.Upload(fileInput.files[0])

WebSocket uses the same equivalence:

js
socket.emit("upload", fileInput.files[0])
gox
socket.On("upload", func(file gox.File) {
    ...
})

GOX is valid for the firm to wait gox.File; a file is not implicitly converted to a structured type. Action Parameters to know the general rules of the arguments.


Receive several files

File[] and FileList become []gox.File and keep order.

gox
func UploadAll(files []gox.File) gox.Action {
    for _, file := range files {
        println(file.Name())
    }
    return true
}
js
const [result, err] = await Actions.UploadAll(fileInput.files)

It can also be used for Array made up exclusively of objects File:

js
const [result, err] = await Actions.UploadAll([avatar, resume])

On WebSocket, the handler can declare the same signature:

gox
socket.On("uploadAll", func(files []gox.File) {
    ...
})

Return a file from a Page

A Page can return a gox.File as HTTP response.

gox
func Download() gox.Page {
    file, err := gox.NewFile(gox.FileConfig{
        Path: "documents/report.pdf",
    })
    if err != nil {
        return err
    }
    return file
}

GOX retains the name, type MIME and size in the response headers. The default is inline.

May be amended Content-Disposition by ctx.Response.Headers before returning the file when the application needs to force a download.

Pages support one single gox.File for response. To deliver several files, create a container like ZIP or use an Action.


Return files from an Action

An Action can return a gox.File:

gox
func Download() gox.Action {
    file, err := gox.NewFile(gox.FileConfig{
        Path: "documents/report.pdf",
    })
    if err != nil {
        return err
    }
    return file
}
js
const [file, err] = await Actions.Download()

console.log(file.name)
console.log(file.type)
console.log(file.size)

The result is a File native to the browser and can be used with your usual APIs:

js
const text = await file.text()
const buffer = await file.arrayBuffer()
const url = URL.createObjectURL(file)

An Action can also return []gox.File:

gox
func DownloadAll() gox.Action {
    return []gox.File{report, invoice}
}
js
const [files, err] = await Actions.DownloadAll()

for (const file of files) {
    console.log(file.name)
}

JavaScript receives a File[] which retains the original order. Return values of Actions to know how the results of an Action are delivered.


Send files via WebSocket

Go can send a file inside an event:

gox
socket.Emit("report", file)
js
socket.on("report", file => {
    console.log(file instanceof File) // true
})

You can also send a collection:

gox
socket.Emit("reports", []gox.File{report, invoice})
js
socket.on("reports", files => {
    for (const file of files) {
        console.log(file.name)
    }
})

The files are transferred along with the event, but are rebuilt as objects File independent in the client. WebSocket events to know how to send and receive the values of an event.


File and Binary

Use gox.File when you need to keep:

  • Nombre.
  • MIME type.
  • Size.
  • File identity in JavaScript.

Use []byte when you only need the bytes. Binary data to know that transfer.


Errors

The operation fails when:

  • Not exactly a source is provided when creating the file.
  • The name is empty, contains route separators or control characters.
  • The MIME type is not valid.
  • The route does not identify a regular file.
  • The content cannot be opened or read.
  • The signature is waiting. gox.File and gets a collection, or vice versa.
  • A Page Attempts to Return []gox.File.

Always check the error of gox.NewFile() before returning or sending the file.


Best practices

  • It uses descriptive and secure names.
  • Declare the MIME type when it cannot be correctly deduced.
  • Check the size before processing received content.
  • Valid the type and content; do not trust only the extension.
  • Close the reader obtained by Open().
  • Use []byte for data without file identity.
  • Use a ZIP when a Page has to deliver several files.
  • Revolve the URL created with URL.createObjectURL() when they cease to be used.

See also

Next step

Continue with HTML to return templates from Go and receive your nodes in JavaScript.

HTML