I want to send the string to the server.My string is like as below,
str := "[{\"name\":\"cpu\",\"status\":\"%d\"}, {\"name\":\"LTE\",\"status\":\"%d\"}, {\"name\":\"Network\",\"status\":\"%d\"}, {\"name\":\"Memory\",\"status\":\"%d\"}]"
When I print it using "fmt.Println(str)",it gives desired output as below,
[{"name":"cpu","status":"%d"}, {"name":"LTE","status":"%d"}, {"name":"Network","status":"%d"}, {"name":"Memory","status":"%d"}]
But when I am sending same string to server,server receives string as below,
"[{\"name\":\"cpu\",\"status\":\"%d\"}, {\"name\":\"LTE\",\"status\":\"%d\"}, {\"name\":\"Network\",\"status\":\"%d\"}, {\"name\":\"Memory\",\"status\":\"%d\"}]"
Please find my code snippet as below:
func (m *MetricSet) Fetch() (common.MapStr, error) {
var x string
x =fmt.Sprintf("[{\"name\":\"cpu\",\"status\":\"%d\"}, {\"name\":\"LTE\",\"status\":\"%d\"}, {\"name\":\"Network\",\"status\":\"%d\"}, {\"name\":\"Memory\",\"status\":\"%d\"}]", 17,26,34,33)
fmt.Println(x)
event := common.MapStr{
"cpu_status": (m.cpu_status%4),
"memory_status" : (m.memory_status%4),
"lte_status" : (m.lte_status%4),
"network_status" : (m.network_status%4),
"summary": x,
}
m.cpu_status++
m.memory_status = m.memory_status + 2
m.lte_status = m.lte_status + 7
m.network_status = m.network_status + 13
return event, nil
}
How to solve it?Please help me.
You are sending the content of summary as a string so, instead you need to send it as a slice of maps
k := [...]common.MapStr{
{"name": "cpu", "status": m.cpu_status},
{"name": "LTE", "status": m.lte_status},
{"name": "Network", "status": m.network_status},
{"name": "Memory", "status": m.memory_status},
}
event := common.MapStr{
"cpu_status": (m.cpu_status % 4),
"memory_status": (m.memory_status % 4),
"lte_status": (m.lte_status % 4),
"network_status": (m.network_status % 4),
"summary": k,
}
See https://play.golang.org/p/yTSXnNKclG
When event is marshalled into JSON, the value of summary will be escaped if it contains a double quote. The quick and dirty solution will be defined the event as map[string]interface{} to be able to store arbitrary type as map value, and store the summary value as json.RawMessage e.g.
event := map[string]interface{}{
"cpu_status": (m.cpu_status%4),
"memory_status" : (m.memory_status%4),
"lte_status" : (m.lte_status%4),
"network_status" : (m.network_status%4),
"summary": json.RawMessage(x),
}
However, you need to make sure that the value of x is a valid JSON object (which is error prone). More robust solution is by defining the items in summary as a struct type, e.g.
type Status struct {
Name string `json:"name"`
Status string `json:"status"`
}
summary := []*Status{
&Status{"cpu", "17"},
&Status{"LTE", "26"},
&Status{"Network", "34"},
&Status{"Memory", "33"},
}
event := map[string]interface{}{
"cpu_status": (m.cpu_status%4),
"memory_status" : (m.memory_status%4),
"lte_status" : (m.lte_status%4),
"network_status" : (m.network_status%4),
"summary": summary,
}
Related
I have a prepared map structure as a string literal. Notice, it is not a JSON! (look at commas in the last elements of blocks)
dict := `{
"ru": {
"test_key": "Тестовый ключ",
"some_err": "Произошла ошибка",
},
"en": {
"test_key": "Test key",
"some_err": "Error occurs",
},
}`
I want to transform this string to real value of map type (map[string]map[string]string). I need it for tests. Is it possible?
If this is just for testing, I would remove the "unneeded" commas from the source string and use JSON unmarshaling.
To remove the unneeded commas: I'd use the regexp ,\s*}, and replace it with a single }.
For example:
dict = regexp.MustCompile(`,\s*}`).ReplaceAllLiteralString(dict, "}")
var m map[string]map[string]string
if err := json.Unmarshal([]byte(dict), &m); err != nil {
panic(err)
}
fmt.Println(m)
Output (try it on the Go Playground):
map[en:map[some_err:Error occurs test_key:Test key] ru:map[some_err:Произошла ошибка test_key:Тестовый ключ]]
I expect that there is no missing value when i serialize and parse, but protoc version 3.9.2 have a problem.
the protofile is show below:
syntax = "proto3";
package example;
message person {
int32 id = 1;
string name = 2;
}
message all_person {
repeated person Per = 1;
}
when i set id=0, name='hello' , i expect to show the "id": 0,
but after SerializeToString and parseToString, it returns
{
"Per": [
{
"name": "hello"
}
]
}
but if i set id=1,name='hello', it returns
{
"Per": [
{
"id": 1,
"name": "hello"
}
]
}
Zero is the default value for numerics (similarly, strings default to empty, booleans to false). See here for more details.
For efficiency, Protobuf relies on these default value. In our system (using FastRTPS and Protobuf for pub/sub), default values are not transmitted across the wire. Based on what you're seeing, it doesn't worry about them for serialisation either.
However, this is only the default behaviour and may be changeable. For example, if you're using MessageToJson, you can simply set an optional parameter including_default_value_fields to True, stating you want the defaults output as well:
jsonStr = MessageToJson(myMsg, True)
i have to insert into a file the result of a mgo query MongoDB converted in Go to get the id of images
var path="/home/Medo/text.txt"
pipe := cc.Pipe([]bson.M{
{"$unwind": "$images"},
{"$group": bson.M{"_id": "null", "images":bson.M{"$push": "$images"}}},
{"$project": bson.M{"_id": 0}}})
response := []bson.M{}
errResponse := pipe.All(&response)
if errResponse != nil {
fmt.Println("error Response: ",errResponse)
}
fmt.Println(response) // to print for making sure that it is working
data, err := bson.Marshal(&response)
s:=string(data)
if err22 != nil {
fmt.Println("error insertion ", err22)
}
Here is the part where I have to create a file and write on it.
The problem is when I got the result of the query in the text file I got an enumeration values in the last of each value for example:
id of images
23456678`0`
24578689`1`
23678654`2`
12890762`3`
76543890`4`
64744848`5`
so for each value i got a number sorted in the last , and i can't figure out how , after getting the reponse from the query i converted the Bson to []Byte and then to Stringbut it keeps me getting that enumeration sorted values in the last of each results
I'd like to drop those 0 1 2 3 4 5
var _, errExistFile = os.Stat(path)
if os.IsNotExist(errExistFile) {
var file, errCreateFile = os.Create(path)
if isError(erro) {
return
}
defer file.Close()
}
fmt.Println("==> done creating file", path)
var file, errii = os.OpenFile(path, os.O_RDWR, 0644)
if isError(errii) {
return
}
defer file.Close()
// write some text line-by-line to file
_, erri := file.WriteString(s)
if isError(erri) {
return
}
erri = file.Sync()
if isError(erri) {
return
}
fmt.Println("==> done writing to file")
You could declare a simple struct eg
simple struct {
ID idtype `bson:"_id"`
Image int `bson:"images"`
}
The function to put the image ids into the file would be
open file stuff…
result := simple{}
iter := collection.Find(nil).Iter()
for iter.Next(&result){
file.WriteString(fmt.Sprintf("%d\n",result.Image))
}
iter.Close()
So, I'm trying to add a string to an existing map that is created from toml.
http://hastebin.com/vayolavose
When I try and build I get the error:
./web.go:56: arguments to copy have different element types: []proxy.Address and string
How would I go about converting it? I've been trying this for the past like 4 hours.
Thanks
while,the code below is your source code
func handleAddFunc(w http.ResponseWriter, r *http.Request) {
backend := r.FormValue("backend")
key := r.FormValue("key")
if !isAuthorized(key) {
respond(w, r, 403, "")
return
}
w.Header().Set("Content-Type", "text/plain")
if !readConfig() {
return
}
activeAddrs = make([]proxy.Address, len(config.Proxy.ServerAddrs))
backendAddr = make([]proxy.Address, len(backend))
copy(backendAddr, config.Proxy.ServerAddrs)
copy(backendAddr, backend)
loadBalancer.SetAddrs(backendAddr)
fmt.Fprintf(w, "Input value of ", backend, "and here is the byte", backendAddr)
}
your code's error, is copy(backendAddr, backend), variable backend is a string value from the request from, you may change this into []proxy.Address, such as (consider I donnot know the struct of proxy.Address ):
var backendAddr = []proxy.Address{}
for _,str := range strings.split(backend,","){
backendAddr = append(backendAddr, &proxy.Address(str))
}
When I parse this little piece of JSON:
{ "value" : 9223372036854775807 }
This is what I get:
{ hello: 9223372036854776000 }
Is there any way to parse it properly?
Not with built-in JSON.parse. You'll need to parse it manually and treat values as string (if you want to do arithmetics with them there is bignumber.js) You can use Douglas Crockford JSON.js library as a base for your parser.
EDIT2 ( 7 years after original answer ) - it might soon be possible to solve this using standard JSON api. Have a look at this TC39 proposal to add access to source string to a reviver function - https://github.com/tc39/proposal-json-parse-with-source
EDIT1: I created a package for you :)
var JSONbig = require('json-bigint');
var json = '{ "value" : 9223372036854775807, "v2": 123 }';
console.log('Input:', json);
console.log('');
console.log('node.js bult-in JSON:')
var r = JSON.parse(json);
console.log('JSON.parse(input).value : ', r.value.toString());
console.log('JSON.stringify(JSON.parse(input)):', JSON.stringify(r));
console.log('\n\nbig number JSON:');
var r1 = JSONbig.parse(json);
console.log('JSON.parse(input).value : ', r1.value.toString());
console.log('JSON.stringify(JSON.parse(input)):', JSONbig.stringify(r1));
Output:
Input: { "value" : 9223372036854775807, "v2": 123 }
node.js bult-in JSON:
JSON.parse(input).value : 9223372036854776000
JSON.stringify(JSON.parse(input)): {"value":9223372036854776000,"v2":123}
big number JSON:
JSON.parse(input).value : 9223372036854775807
JSON.stringify(JSON.parse(input)): {"value":9223372036854775807,"v2":123}
After searching something more clean - and finding only libs like jsonbigint, I just wrote my own solution. Is not the best, but it solves my problem. For those that are using Axios you can use it on transformResponse callback (this was my original problem - Axios parses the JSON and all bigInts cames wrong),
const jsonStr = `{"myBigInt":6028792033986383748, "someStr":"hello guys", "someNumber":123}`
const result = JSON.parse(jsonStr, (key, value) => {
if (typeof value === 'number' && !Number.isSafeInteger(value)) {
let strBig = jsonStr.match(new RegExp(`(?:"${key}":)(.*?)(?:,)`))[1] // get the original value using regex expression
return strBig //should be BigInt(strBig) - BigInt function is not working in this snippet
}
return value
})
console.log({
"original": JSON.parse(jsonStr),
"handled": result
})
A regular expression is difficult to get right for all cases.
Here is my attempt, but all I'm giving you is some extra test cases, not the solution. Likely you will want to replace a very specific attribute, and a more generic JSON parser (that handles separating out the properties, but leaves the numeric properties as strings) and then you can wrap that specific long number in quotes before continuing to parse into a javascript object.
let str = '{ "value" : -9223372036854775807, "value1" : "100", "strWNum": "Hi world: 42 is the answer", "arrayOfStrWNum": [":42, again.", "SOIs#1"], "arrayOfNum": [100,100,-9223372036854775807, 100, 42, 0, -1, 0.003] }'
let data = JSON.parse(str.replace(/([:][\s]*)(-?\d{1,90})([\s]*[\r\n,\}])/g, '$1"$2"$3'));
console.log(BigInt(data.value).toString());
console.log(data);
you can use this code for change big numbers to strings and later use BigInt(data.value)
let str = '{ "value" : -9223372036854775807, "value1" : "100" }'
let data = JSON.parse(str.replace(/([^"^\d])(-?\d{1,90})([^"^\d])/g, '$1"$2"$3'));
console.log(BigInt(data.value).toString());
console.log(data);