Skip to content

Instantly share code, notes, and snippets.

@albrow
Created April 18, 2015 23:18
Show Gist options
  • Save albrow/ad21d103c507c380a2e7 to your computer and use it in GitHub Desktop.
Save albrow/ad21d103c507c380a2e7 to your computer and use it in GitHub Desktop.
Non-Blocking ReadAll function for Humble
// ReadAll expects a pointer to a slice of poitners to some concrete type
// which implements Model (e.g., *[]*Todo). GetAll will send a GET request to
// a RESTful server and scan the results into models. It expects a json array
// of json objects from the server, where each object represents a single Model
// of some concrete type. It will use the RootURL() method of the models to
// figure out which url to send the GET request to.
func ReadAll(models interface{}) <-chan error {
// We expect some pointer to a slice of models. Like *[]Todo
// First Elem() givew us []Todo
// Second Elem() gives us Todo
modelsType := reflect.TypeOf(models).Elem()
// TODO: type checking!
modelTypePtr := modelsType.Elem()
modelType := modelTypePtr.Elem()
// reflect.New returns *Todo
newModelVal := reflect.New(modelType)
newModelInterface := newModelVal.Interface()
newModel := newModelInterface.(Model)
// TODO: check for a failed type assertion!
urlRoot := newModel.RootURL()
// Send the http request inside a goroutine
errChan := make(chan error)
go func() {
res, err := http.Get(urlRoot)
if err != nil {
errChan <- fmt.Errorf("Something went wrong with GET request to %s. %s", urlRoot, err.Error())
return
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
errChan <- fmt.Errorf("Error reading response body from GET request to %s: %s", urlRoot, err.Error())
return
}
if err := json.Unmarshal(body, models); err != nil {
errChan <- fmt.Errorf("Failed to unmarshal response into object, with Error: %s.\nResponse was: %s", err)
return
}
errChan <- nil
}()
return errChan
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment