5

I have created a function to get some data and write them to CSV and the output is stored on a buffer.

type OptIn struct {
    Email      string `json:"email"`
    LastUpdate string `json:"opt_in_last_update"`
}

func writeCSV(data []OptIn) ([]byte, error) {
    var buf bytes.Buffer
    writer := csv.NewWriter(&buf)

    defer writer.Flush()

    for _, obj := range data {
        var record []string
        record = append(record, obj.Email)
        record = append(record, obj.LastUpdate)
        err := writer.Write(record)
        if err != nil {
            panic(err.Error())
        }
    }

    return buf.Bytes(), nil
}

The problem is that the buf.Bytes() is always empty, even though the input is not empty and there are no errors thrown.

1
  • 4
    You are calling Bytes() before Flush(). Commented Aug 24, 2018 at 15:33

1 Answer 1

11

You need to call writer.Flush() before calling .Bytes() and check .Error() before returning:

  // TODO: remove `defer writer.Flush()`
  // ...

  writer.Flush()

  if err := writer.Error(); err != nil {
    return nil, err
  }

  return buf.Bytes(), nil
}

Your sample code does things in the following order:

  1. call buf.Bytes()
  2. return the generated byte slice and nil
  3. call writer.Flush()

Clearly this is not the intended order since we need to flush (and check for any writer errors!) before accessing the generated byte slice.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.