Search code examples
jsongodata-bindinggo-echo

Is it possible to bind to map object of custom struct type?


my question is, how to bind(auto binding?) custom structure type in a map object(variable)?

this is my custom struct type

type Tetris struct {
    ... ...
    NowBlock           map[string]int     `form:"nowBlock" json:"nowBlock"`
    ... ...
}

this is my ajax code

 $.ajax({
     type : "POST"
     , url : "/game/tetris/api/control"
     , data : {
                "keyCode" : keyCode
                , "ctxWidth" : ctxWidth
                , "ctxHeight" : ctxHeight
                , "nowBlock" : {"O":0}
     } // also, i did JSON.stringify, but did not binding..
     , dataType : "json"
     , contentType : "application/json"
     }).done(function(data){
           ... ...
 });

and then, do not binding 'NowBlock'

tetris := new(Tetris)
if err := c.Bind(tetris); err != nil {
    c.Logger().Error(err)
}
fmt.Println(tetris.NowBlock)

the println result is ,

'map[]' //nil...

this is my full question link(GOLANG > How to bind ajax json data to custom struct type?)

please help me.



ps. thank you for answer me. I did like the answer. BUT, it does not working too.

First,

- No 'contentType : "application/json"'
- don't use JSON.stringify

 then, in go side, 
- fmt.println(tetris.KeyCode) // OK
- fmt.println(tetris.NowBlock) // NOT OK.. 'map[]'

Second,

- Use 'contentType : "application/json"'
- Use JSON.stringify

then, in go side, 
- fmt.println(tetris.KeyCode) // NOT OK.. '' (nil)
- fmt.println(tetris.NowBlock) // NOT OK.. 'map[]'

Third,

i remove the custom struct type Tetris NowBlock object's `form:nowBlock` literal, 
but is does not working too...

why not binding Custom structure type in a map object?




i'm so so sorry. i solve this question. the problem that is my go custom struct type have another custom struct type.

like this.

type Tetris struct {
    Common Common

    NowBlock           map[string]int     `json:"nowBlock"`
}

type Common struct {
    CtxWidth  int `json:"ctxWidth"`
    CtxHeight int `json:"ctxHeight"`

    KeyCode int `form:"keyCode" json:"keyCode"`
}

in this case, i did

 $.ajax({
 type : "POST"
 , url : "/game/tetris/api/control"
 , data : {
            "keyCode" : keyCode
            , "ctxWidth" : ctxWidth
            , "ctxHeight" : ctxHeight
            , "nowBlock" : {"O":0}
 } // also, i did JSON.stringify, but did not binding..
 , dataType : "json"
 , contentType : "application/json"
 }).done(function(data){
       ... ...

});

but, this is wrong! the correct is,

$.ajax({
    type : "POST"
    , url : "/game/tetris/api/control"
    , data : JSON.stringify({
        "Common" : {
            "keyCode" : keyCode
            , "ctxWidth" : ctxWidth
            , "ctxHeight" : ctxHeight
        }
        , "nowBlock" : {"O":0}
    })
    , dataType : "json"
    , contentType : "application/json"
}).done(function(data){
   ... ...

in json data, 'Common' struct type's data must have "Common" 'Key:value' map...

i'm very glade to your answers and attentions.


Solution

  • There is no problem in your go code. Why echo .Bind() not able to retrieve the payload sent from AJAX is because the payload is not in JSON format.

    On $.ajax you need to JSON.stringify() the data into JSON string format.

    JSON.stringify({
        "keyCode" : keyCode
        , "ctxWidth" : ctxWidth
        , "ctxHeight" : ctxHeight
        , "nowBlock" : {"O":0}
    })
    

    Setting contentType into application/json will not automatically convert payload into JSON string. That's why JSON.stringy() is still required.


    Full changes:

    var payload = JSON.stringify({
        "keyCode": keyCode,
        "ctxWidth": ctxWidth,
        "ctxHeight": ctxHeight,
        "nowBlock": {
            "O": 0
        }
    })
    
    $.ajax({
        type: "POST",
        url: "/game/tetris/api/control",
        data: payload,
        dataType: "json",
        contentType: "application/json"
    }).done(function(data) {
        ......
    });