Problems with JsonObj:Json_hash

Asked

Viewed 241 times

0

I am new to advpl, and need to create a Hashmap object. I will leave part of my code to see if you can help me.

If !empty(cJsonCOT)
    // Cria o objeto para fazer o parser do Json
    oJsonObj := tJsonParser():New()

    // Faz o Parser da mensagem JSon e extrai para Array (aJsonfields) e cria tambem um HashMap para os dados da mensagem (oJHM)
    lRet := oJsonObj:Json_Hash(cStrJson, nLenStrJson, @aJsonfields, @nRetParser, @oJHashMap)

        If ( !lRet )
            MsgStop(cStrJson,"Falha ao solicitar dados")
        else
            // Obtem o valor dos campos usando o Hashmap gerado
            HMGet(oJHashMap, "erro", @lCotERRO)
            If lCotERRO
                MsgStop("##### [JSON][ERR] " + "Parser com erro" + " MSG len: " + AllTrim(Str(nLenStrJson)) + " bytes lidos: " + AllTrim(Str(nRetParser)))
            Else
                // Obtem o valor dos campos usando a chave
                HMGet(oJHashMap, "valorCompra", cCompra)
            ENDIF
        ENDIF
    // Limpa os objetos utilizados
    FreeObj(oJsonObj)
    FreeObj(oJHashMap)
ENDIF

The only thing I can’t do is create the object -> @oJHashMap

All variables are declared according to their type.

All these parameters are fine (Strjson, nLenStrJson, @aJsonfields, @nRetParser). They have their correct data.

lRet := oJsonObj:Json_hash(cStrJson, nLenStrJson, @aJsonfields, @nRetParser, @oJHashMap) -> But in this line, according to the theory (which I obviously don’t understand), this object must be created. But it doesn’t happen, it just has nothing.

This code is just an example. From this object, I need several data. That in the example I am looking for only one. Because my problem is that the object is not being created for some reason.

  • Daregny, your goal is just to get the value of JSON?

2 answers

0


In ADVPL, it is possible to parse a JSON in more than one way.

We can use the hashmap and Tjsonparser as you were implementing, but you can also use Jsonobject, which makes the code much simpler.

Here’s an example, using your code to return the Compra value, and also an implementation using Jsonobject:

#include "protheus.ch"

user function JSONExample()
local cStrJson as char

cStrJson := '{"valorCompra": "1.075,80"}'

//TJsonParser e Hashmap
ConOut( getVlrHashMap( cStrJson) )

cStrJson := '{"value":[{"cotacaoCompra": 4.13700, "cotacaoVenda": 4.13760, "dataHoraCotacao": "2019-10-18 13:09:37.206"}]}'

//JSONObject
ConOut( getVlrJSONObj( cStrJson) )

return nil

static function getVlrHashMap(cJSON)
local cCompra as char
local nLenStrJson as numeric
local aJsonfields as array
local nRetParser as numeric
local lRet as logical
local oJsonObj as object
local oJHashMap as object
local lCotERRO as logical

//EXEMPLO UTILIZANDO TJsonParser E Hashmap
if !Empty(cJSON)
    // Cria o objeto para fazer o parser do Json
    oJsonObj := TJsonParser():New()
    nLenStrJson := Len(cJSON)
    aJsonfields := {}
    nRetParser := 0

    // Faz o Parser da mensagem JSon e extrai para Array (aJsonfields) e cria tambem um HashMap para os dados da mensagem (oJHM)
    lRet := oJsonObj:Json_Hash(cJSON, nLenStrJson, @aJsonfields, @nRetParser, @oJHashMap)

    if ( !lRet )
        MsgStop(cJSON,"Falha ao solicitar dados")
    else
        // Obtem o valor dos campos usando o Hashmap gerado
        HMGet(oJHashMap, "erro", @lCotERRO)

        if lCotERRO
            //É possível utilizar cValToChar no lugar de AllTrim(Str(nLenStrJson))
            MsgStop("##### [JSON][ERR] " + "Parser com erro" + " MSG len: " + AllTrim(Str(nLenStrJson)) + " bytes lidos: " + AllTrim(Str(nRetParser)))
        else
            // Obtem o valor dos campos usando a chave
            HMGet(oJHashMap, "valorCompra", @cCompra)
        endif
    endif

    // Limpa os objetos utilizados
    FreeObj(oJsonObj)
    FreeObj(oJHashMap)
endif

return cCompra

static function getVlrJSONObj(cJSON)
local cCompra as char
local cError as char
local jJSON

//EXEMPLO UTILIZANDO JSONObject
if !Empty(cJSON)
    //Classe responsável por trabalhar com JSON em ADVPL
    jJSON := JSONObject():New()

    //Efetuar o parser do JSON
    cError := jJSON:FromJSON(cJSON)

    //Se vazio, não foi gerado erro no parser
    if Empty(cError)
        //Sintaxe simples, mais próximo ao utilizado em JS
        cCompra := jJSON['value'][1]['cotacaoCompra']
    else
        MsgStop("Parser error: " + cError)
    endif
endif

return cCompra

The getVlrHashMap function is based on its code, while getVlrJSONObj uses Jsonobject.


References:

https://tdn.totvs.com/display/tec/Classe+JsonObject

https://tdn.totvs.com/display/tec/Classe+TJsonParser

https://tdn.totvs.com/display/tec/HMGet

  • Thank you so much for your help... But it doesn’t work... :(... I think my problem is the json itself.

  • Generated any parser error? Need to check how is this JSON, if it is with some error, none of the ways will work.

  • I’ll put the details so you can see.

0

That’s how it works.

Static function GetVlrJSONObj(cJsonCOT)
Local cCotCompra, cErro
Local oJsonObj

If !Empty(cJsonCOT)
    //Classe responsável por trabalhar com JSON em ADVPL
    oJsonObj := JSONObject():New()

    //Efetuar o parser do JSON
    cError := oJsonObj:FromJSON(cJsonCOT)

    //Se vazio, não foi gerado erro no parser
    if Empty(cErro)
        //Sintaxe simples, mais próximo ao utilizado em JS
        cCotCompra := oJsonObj['cotacaoCompra']
    else
        MsgStop("Parser error: " + cError)
    endif
endif

Return cCotCompra

E este é o Json e o resultado.

  • Puts the received JSON on it here, but not in image. Calling the function generated parser error?

  • Does not generate error because the variable has a "J". In the image is the Json (cJsonCot) in the String format and the result when we transform it into the object (oJsonObj).

  • Does Json come from an API -> https://olinda.bcb.gov.br/olinda/servico/PTAX/versao/v1/odata/CotacaoDolarDia(dataCotacao=@dataCotacao)? %40dataCotacao=%2709-30-2019%27&$format=json

  • Daregny, I changed the example with a JSON equal to yours, take a look, but in the generate, it happens that to get the value quotoCompra, it is necessary to access the property value (array) and in the first position of the same, then take the value quotoCompra: cCompra := jJSON['value'][1]['cotacaooCompra']

  • Thank you very much!!!!!! You were right ... Sorry my ignorance, the truth is the first time I work with a Json ...

  • Show! Just be aware that I fixed the positions in the example to always pick the first position of the array etc. =)

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.