gohyperledger-fabrichyperledgerchaincode

Error while trying to fetch queryresult.KV object in JSON.Unmarshal


I am a little bit confused here and although I have searched a lot on this, something is clearly missing from my knowledge and I am asking your help.

I have created a Hyperledger Fabric Network and installed a chaincode in it. And I want to make a function that retrieves all the World State inputs about the Keys. I have done it already with the bytes.Buffer and it worked. But what I want to do is to do it with a struct.

So, I created the following struct that has only the key:

type WSKeys struct {
    Key             string `json: "key"`
    Namespace       string `json: "Namespace"`
}

And this is my code function:

func (s *SmartContract) getAllWsDataStruct(APIstub shim.ChaincodeStubInterface , args []string) sc.Response {

    var keyArrayStr []WSKeys

    resultsIterator, err := APIstub.GetQueryResult("{\"selector\":{\"_id\":{\"$ne\": null }} }")
    if err != nil {
        return shim.Error("Error occured when trying to fetch data: "+err.Error())
    }

    for resultsIterator.HasNext()  {
        // Get the next record
        queryResponse, err := resultsIterator.Next()
        if err != nil {
            return shim.Error(err.Error())
        }
        fmt.Println(queryResponse)

        var qry_key_json WSKeys
        
        json.Unmarshal([]byte(queryResponse), &qry_key_json)
        
        keyArray = append(keyArray, qry_key_json)

    }
    defer resultsIterator.Close()

    all_bytes, _ := json.Marshal(keyArray)
    fmt.Println(keyArray)
    return shim.Success(all_bytes)
}

When executing the above I get the following error:

cannot convert queryResponse (type *queryresult.KV) to type []byte

I can get the results correctly if I, for example do this:

func (s *SmartContract) getAllWsDataStruct(APIstub shim.ChaincodeStubInterface , args []string) sc.Response {

    var keyArray []string

    resultsIterator, err := APIstub.GetQueryResult("{\"selector\":{\"_id\":{\"$ne\": null }} }")
    if err != nil {
        return shim.Error("Error occured when trying to fetch data: "+err.Error())
    }

    for resultsIterator.HasNext()  {
        // Get the next record
        queryResponse, err := resultsIterator.Next()
        if err != nil {
            return shim.Error(err.Error())
        }
        fmt.Println(queryResponse)
        
        
        keyArray = append(keyArray, queryResponse.Key)

    }
    defer resultsIterator.Close()

    all_bytes, _ := json.Marshal(keyArray)
    fmt.Println(keyArray)
    return shim.Success(all_bytes)
}

But, why I get the above error when trying to add the queryResponse into a custom struct? Do I need to add it to a struct that is only its type?

Please someone can explain what I am missing here?


Solution

  • The error statement is verbose enough to indicate, that your []byte conversion failed for the type queryResponse which, with a bit of lookup seems to be a struct type. In Go you cannot natively convert a struct instance to its constituent bytes without encoding using gob or other means.

    Perhaps your intention was to use the Key record in the struct for un-marshalling

    json.Unmarshal([]byte(queryResponse.Key), &qry_key_json)