gabs icon indicating copy to clipboard operation
gabs copied to clipboard

Appending to an object in an array does not work

Open geoynomous opened this issue 4 years ago • 4 comments

    // Create JSON with "outer" array field
    jsonObj := gabs.New()
    jsonObj.Array("outer")

    // Create JSON with "inner" array field
    innerObj := gabs.New()
    innerObj.ArrayOfSize(0, "inner")

    // Append to inner
    jsonObj.ArrayAppend(innerObj, "outer");

    // Create data JSON
    data := gabs.New()
    data.Set(1, "value")

    // Create a jsonpath
    jsonPath := "outer.0.inner"

    // Count array size of path
    counterInner, _ := jsonObj.ArrayCountP(jsonPath)
    log.Print("#Count BEFORE: ", counterInner)

    // Appent to path (inner)
    jsonObj.ArrayAppendP(data, jsonPath)

    // Count again
    counterInner, _ = jsonObj.ArrayCountP(jsonPath)
    log.Print("#Count AFTER : ", counterInner)
    // BOOM! Nothing is added

It is similar to https://github.com/Jeffail/gabs/issues/91 - please fix it!

geoynomous avatar Apr 12 '21 08:04 geoynomous

Here is a fix!

diff --git a/gabs.go b/gabs.go
index c75e8de..7c649e6 100644
--- a/gabs.go
+++ b/gabs.go
@@ -143,6 +143,8 @@ func (g *Container) searchStrict(allowWildcard bool, hierarchy ...string) (*Cont
                        if !ok {
                                return nil, fmt.Errorf("failed to resolve path segment '%v': key '%v' was not found", target, pathSeg)
                        }
+               } else if g2, ok := object.(*Container); ok {
+                       return g2.searchStrict(false, hierarchy[target:]...)
                } else if marray, ok := object.([]interface{}); ok {
                        if allowWildcard && pathSeg == "*" {
                                tmpArray := []interface{}{}
@@ -308,6 +310,8 @@ func (g *Container) Set(value interface{}, hierarchy ...string) (*Container, err
                                mmap[pathSeg] = map[string]interface{}{}
                                object = mmap[pathSeg]
                        }
+               } else if g2, ok := object.(*Container); ok {
+                       return g2.Set(value, hierarchy[target:]...)
                } else if marray, ok := object.([]interface{}); ok {
                        if pathSeg == "-" {
                                if target < 1 {

geoynomous avatar Apr 13 '21 08:04 geoynomous

is this read?

geoynomous avatar Apr 21 '21 10:04 geoynomous

Hey @geoynomous, sorry, I've not been very attentive to this repo. The line jsonObj.ArrayAppend(innerObj, "outer") needs to insert the underlying array rather than a gabs container, so it should be jsonObj.ArrayAppend(innerObj.Data(), "outer"), and the same goes for jsonObj.ArrayAppendP(data, jsonPath), which should be jsonObj.ArrayAppendP(data.Data(), jsonPath).

You will likely also need to rearrange some of this so that mutations of arrays are performed before inserting the array into a parent object, since arrays are reference types but the reference might change during append operations.

Jeffail avatar Apr 21 '21 13:04 Jeffail

Thanks - that works .. but still I think it's a bug - as the execution finishes without an error reported, but no effect takes places. So either create an error - or apply the fix from above - or if it's a gabs container given call .Data() on it and proceed with that

geoynomous avatar Apr 25 '21 14:04 geoynomous