Mergo not overriding destination with source
RomilShah opened this issue · comments
I am trying to merge values of 2 JSON into 1, where value of source should override value of destination. It is working fine for most the cases except for the case where value of 1 hashmap is string and other value is another hashmap. Below is the code snipped
package main
import (
"encoding/json"
"fmt"
"github.com/imdario/mergo"
)
var (
a = "{\"a\": \"60\"}"
b = "{\"a\": { \"name\":\"asprin\", \"dose\":0.12,\"stt\":true} }"
)
func main() {
var source, destination map[string]interface{}
err := json.Unmarshal([]byte(a), &destination)
if err != nil {
panic(err)
}
err = json.Unmarshal([]byte(b), &source)
if err != nil {
panic(err)
}
fmt.Println(destination, source)
err = mergo.MergeWithOverwrite(&destination, &source, mergo.WithOverride, mergo.WithTypeCheck)
if err != nil {
panic(err)
}
fmt.Println(&destination, " <-- result")
}
playground: https://go.dev/play/p/BTmRc7wf6Js
Current output is
&map[a:60] <-- result which is value of destination. Mergo is not changing anything
Excepted output is
map[a:map[dose:0.12 name:asprin stt:true]] <--result
or at-least give error that it is not possible to merge hashmap to string`
It looks like you're looking for something like github.com/mitchellh/mapstructure instead which is exactly tailored for use cases “where you don't quite know the structure of the underlying data until you read a part of it“. In your case a
is a number in the first map, bur changes to a object in the second which is a different type. mergo
is strong when it comes to merging struct
s o the same type.
mergo
provides a Map
function, but mapstructure
fits better because it is the main goal of the project to handle map
s.
@RomilShah This code works as you expected:
package main
import (
"encoding/json"
"fmt"
"dario.cat/mergo"
)
var (
a = "{\"a\": \"60\"}"
b = "{\"a\": { \"name\":\"asprin\", \"dose\":0.12,\"stt\":true} }"
)
func main() {
var source, destination map[string]interface{}
err := json.Unmarshal([]byte(a), &destination)
if err != nil {
panic(err)
}
err = json.Unmarshal([]byte(b), &source)
if err != nil {
panic(err)
}
err = mergo.Map(&destination, source, mergo.WithOverride)
if err != nil {
panic(err)
}
fmt.Println(destination, " <-- result")
}
It even works if you use Merge instead of Map, making mergo equivalent to mapstructure. Merging structs or maps is the same logic, although in Mergo Map is a specialized case of Merge.