Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net/url: Stitching complex arrays #29703

Closed
qingwg opened this issue Jan 12, 2019 · 4 comments
Closed

net/url: Stitching complex arrays #29703

qingwg opened this issue Jan 12, 2019 · 4 comments

Comments

@qingwg
Copy link

qingwg commented Jan 12, 2019

What version of Go are you using (go version)?

$ go version
go version go1.11.4 linux/amd64

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/qingwuguo/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/qingwuguo/go"
GOPROXY=""
GORACE=""
GOROOT="/home/linuxbrew/.linuxbrew/Cellar/go/1.11.4/libexec"
GOTMPDIR=""
GOTOOLDIR="/home/linuxbrew/.linuxbrew/Cellar/go/1.11.4/libexec/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc-5"
CXX="g++-5"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build223599200=/tmp/go-build -gno-record-gcc-switches"

What did you do?

I want to get a query string.
If like this,I can

type B struct {
	ItemC string `json:"c"`
}

structB := B{
	ItemC: "c",
}

var params = url.Values{}
jsonbs, _ := json.Marshal(structB)
jsonmap := make(map[string]interface{})
json.Unmarshal(jsonbs, &jsonmap)
for k, v := range jsonmap {
	params.Add(k, fmt.Sprintf("%v", v))
}
fmt.Println(params.Encode())

Bug if complex arrays,like this

type A struct {
	ItemB B `json:"b"`
}

type B struct {
	ItemC string `json:"c"`
}

structB := B{
	ItemC: "c",
}
structA := A{
	ItemB: structB,
}

var params = url.Values{}
jsonbs, _ := json.Marshal(structA)
jsonmap := make(map[string]interface{})
json.Unmarshal(jsonbs, &jsonmap)
for k, v := range jsonmap {
	switch t := v.(type) {
	default:
		params.Add(k, fmt.Sprintf("%v", v))
	case map[string]interface{}:
		for kk, vv := range t {
			// this I do not know what to do
		}
	}
}
fmt.Println(params.Encode())
@agnivade
Copy link
Contributor

It is not clear to me how you want the net/url package to help here.

Why can't you just do -

case map[string]interface{}:
  res, _  := json.Marshal(t)
  params.Add(k, fmt.Sprintf("%s", res))

That prints b=%7B%22c%22%3A%22c%22%7D, which gets nicely parsed back to the original value -

m, err := url.ParseQuery(`b=%7B%22c%22%3A%22c%22%7D`)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(m) // map[b:[{"c":"c"}]]

@agnivade agnivade added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Jan 12, 2019
@qingwg
Copy link
Author

qingwg commented Jan 12, 2019

I want to

user[name]=&user[age]=test2&user[sex]=test3

like PHP example http_build_query() with complex arrays

<?php
$data = array(
    'user' => array(
        'name' => 'Bob Smith',
        'age'  => 47,
        'sex'  => 'M',
        'dob'  => '5/12/1956'
    ),
    'pastimes' => array('golf', 'opera', 'poker', 'rap'),
    'children' => array(
        'bobby' => array('age'=>12, 'sex'=>'M'),
        'sally' => array('age'=>8, 'sex'=>'F')
    ),
    'CEO'
);

echo http_build_query($data, 'flags_');
?>

this will output : (word wrapped for readability)

user[name]=Bob+Smith&user[age]=47&user[sex]=M&
user[dob]=5/12/1956&pastimes[0]=golf&pastimes[1]=opera&
pastimes[2]=poker&pastimes[3]=rap&children[bobby][age]=12&
children[bobby][sex]=M&children[sally][age]=8&
children[sally][sex]=F&flags_0=CEO

@agnivade

@agnivade
Copy link
Contributor

Thanks for the clarification. It would have helped if you would have mentioned this in the first place up-front.

I think you will have to write your own logic to parse the json and build your query keys, or use some external library which can help you to easily iterate nested keys. net/url cannot help here.

If you would want something like this to be in the standard library, please open a separate proposal issue clealy mentioning why you want something like this in the standard library (also see - https://golang.org/doc/faq#x_in_std).

@agnivade agnivade removed the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Jan 12, 2019
@qingwg
Copy link
Author

qingwg commented Jan 12, 2019

thanks
@agnivade

@qingwg qingwg closed this as completed Jan 12, 2019
@golang golang locked and limited conversation to collaborators Jan 12, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants