I have this code in a router handler
decoder := json.NewDecoder(r.Body)
var t person.Model
err := decoder.Decode(&t). // t is a struct value
item, ok := v.People[params["id"]]. // ok is a struct value
if t.Handle != "" {
item.Handle = t.Handle
}
if t.Work != "" {
item.Work = t.Work
}
if t.Image != "" {
item.Image = t.Image
}
if t.Firstname != "" {
item.Firstname = t.Firstname
}
if t.Lastname != "" {
item.Lastname = t.Lastname
}
if t.Email != "" {
item.Email = t.Email
}
But I would like to make this dynamic, something like this:
["Handle", "Work", "Image", "Firstname", "Lastname", "Email"].forEach(v => {
if t[v] != "" {
item[v] = t[v]
}
});
is this possible with Golang somehow?
Use the reflect package for this:
func setFields(dst, src interface{}, names ...string) {
d := reflect.ValueOf(dst).Elem()
s := reflect.ValueOf(src).Elem()
for _, name := range names {
df := d.FieldByName(name)
sf := s.FieldByName(name)
switch sf.Kind() {
case reflect.String:
if v := sf.String(); v != "" {
df.SetString(v)
}
// handle other kinds
}
}
}
Call it with pointers to the values:
setFields(&item, &t, "FirstName", "LastName", "Email", "Handle")
If your actual goal is to overwrite only the fields present in the JSON, then do just that:
item, ok := v.People[params["id"]].
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&item)