Page 1 of 2

Reading JSON String from structure

Posted: Fri Jun 19, 2020 7:55 am
by menschmarkus
Hi,
I am a little confused. Following Situation:
My basic call is:

Code: Select all

HTTPRequest(#PB_HTTP_Post,URL,URLEncoder(Query),@checkLoginData())
which works fine
then

Code: Select all

Structure rLogin
Login.s
EndStructure
Structure login
  Owner.s
  USER.s
  STATUS.i
  List RESULT.rLogin()
EndStructure
Procedure  checkLoginData(Success,Result.s,UserData)
  Protected Query.s
  MessageRequester("(CheckLoginData 1)" + Chr(10) + Result)            ;==> SHOWS JSON CORRECTLY
  If Success
    If ParseJSON(#JSON,Result)
      ExtractJSONStructure(JSONValue(#JSON),@Login,login)      
        MessageRequester("(CheckLoginData 2)" + Chr(10) + Login\STATUS + Chr(10) + Login\RESULT()\Login) 
    Else
      MessageRequester("Login Parse error") 
    EndIf
  Else
    MessageRequester("Login Server request failed")
  EndIf 
EndProcedure
The values in Message (CheckLoginData 2) are not shown immediately. Repeating this request will show valid values. What is necessary to call structure values immediately after extracting JSON structure

Thank you for usefull replies

Edit: (Post corrected !)

Re: Reading JSON String from structure

Posted: Fri Jun 19, 2020 8:24 am
by Peter
menschmarkus wrote:

Code: Select all

ExtractJSONStructure(JSONValue(#JSON),@Login,suche)
Shouldn't it look that way?

Code: Select all

ExtractJSONStructure(JSONValue(#JSON),@Login,login)

Re: Reading JSON String from structure

Posted: Fri Jun 19, 2020 8:31 am
by menschmarkus
You're right. Type Mismatch from my side here in this post. The original call is correct :oops:

Extending information:
To be sure I placed the messagerequester behind the httprequest callback. But the effect is the same. Valid result appears earliest after second call.

2nd. Extending information:
In the meantime I started Browser Debugger and checked what happens. Following the Browser Error Message

Code: Select all

TypeError: v_login._RESULT.current is null
  f_loginhandler             project.js:1074
  f_readfileparameter   project.js:954
  f                                     project.js:372
  g                                     project.js:372
...to be continued ....
So I checked the project.js Line numbers and found following:

Code: Select all

954:spider_CreateMapElement(m_parameter,_S55)._wz=spider_Val(spider_StringField(v_readline,2,_S136));
1074:spider_MessageRequester(_S124+spider_Str(v_login._STATUS)+_S125+v_login._RESULT.current._Login);
I don't know if it helps but this is the point where Debugger stopps due to an exception.

By the way there are 7 further warnings like "using zoom instead calc() in nproject.html file" (1x) or
"Source-map-error: Error: request failed with status 404 in dojo.js" (3x) or
"onmozfullscreenchange should not be used any longer" (2x) and finally
"get" or "set" of a condition is ignored due to the "ths"-object is faulty" (1x)

but this is more interesting for Fred I can imagine.

Re: Reading JSON String from structure

Posted: Fri Jun 19, 2020 2:13 pm
by Paul
menschmarkus wrote:You're right. Type Mismatch from my side here in this post. The original call is correct :oops:

Extending information:
To be sure I placed the messagerequester behind the httprequest callback. But the effect is the same. Valid result appears earliest after second call.
Without seeing your server side code or whatever else you have for your SpiderBasic code, I can't comment what the problem might be but using your code snippet and a small PureBasic CGI to send data back... it works fine here.

Code: Select all

Structure rLogin
  Login.s
EndStructure
Structure login
  Owner.s
  USER.s
  STATUS.i
  List RESULT.rLogin()
EndStructure


#JSON=0
URL.s="https://reelmedia.org/cgi-bin/logintest.exe"
Query.s="test=hello"

Procedure  checkLoginData(Success,Result.s,UserData)
  Protected Query.s
  Debug "(CheckLoginData 1)" + Chr(10) + Result            ;==> SHOWS JSON CORRECTLY
  If Success
    If ParseJSON(#JSON,Result)
      ExtractJSONStructure(JSONValue(#JSON),@login.login,login)     
      Debug "(CheckLoginData 2)"+Chr(10)+login\Owner+Chr(10)+login\STATUS+Chr(10)+login\RESULT()\Login
      Else
      Debug "Login Parse error"
    EndIf
    Else
    Debug "Login Server request failed"
  EndIf
EndProcedure

HTTPRequest(#PB_HTTP_Post,URL,URLEncoder(Query),@checkLoginData())
Compiled as logintest.exe and saved in my cgi-bin folder on my server...

Code: Select all

If Not InitCGI() Or Not ReadCGI()
  End
EndIf


Structure rLogin
  Login.s
EndStructure
Structure login
  Owner.s
  USER.s
  STATUS.i
  List RESULT.rLogin()
EndStructure
cgi.login

  
test$ =CGIParameterValue("test")


WriteCGIHeader("Access-Control-Allow-Origin", "*")  ;<----------- Remove for Final Release  !!!!!!
WriteCGIHeader(#PB_CGI_HeaderContentType,"text/html",#PB_CGI_LastHeader)


If test$="hello"
  hJSON=CreateJSON(#PB_Any)
  If hJSON
    cgi\Owner="Owner 1"   
    cgi\USER="User 1"  
    cgi\STATUS=111
    AddElement(cgi\RESULT())
    cgi\RESULT()\Login="Final Result"  
    InsertJSONStructure(JSONValue(hJSON), @cgi, login)
    web$=ComposeJSON(hJSON)
    WriteCGIString(web$)
    FreeJSON(hJSON)
  EndIf  
EndIf    
End

Re: Reading JSON String from structure

Posted: Fri Jun 19, 2020 2:43 pm
by Peter
menschmarkus wrote:

Code: Select all

TypeError: v_login._RESULT.current is null

Code: Select all

1074:spider_MessageRequester(_S124+spider_Str(v_login._STATUS)+_S125+v_login._RESULT.current._Login);
seems, that login\RESULT() has no elements.

Re: Reading JSON String from structure

Posted: Fri Jun 19, 2020 5:11 pm
by menschmarkus
seems, that login\RESULT() has no elements.
hm, should I change the structure? here the JSON I have to extract.

Code: Select all

{"Owner":"1234567890","USER":"0987654321","STATUS":20,"Restkontingent":null,"RESULT":[{"Login":"Benutzerdaten sind korrekt"}]}
Peter, what is your proposal for a structure?
Should I use a "List" or a "MAP" for result. I tried both without success.
If you could write a structure sample it would be helpful for me.

Re: Reading JSON String from structure

Posted: Fri Jun 19, 2020 9:37 pm
by Peter
Your JSON and structure seem to be OK:

Code: Select all

EnableExplicit

Structure rLogin
  Login.s
EndStructure
Structure login
  Owner.s
  USER.s
  STATUS.i
  List RESULT.rLogin()
EndStructure

Define Result.s = ~"{\"Owner\":\"1234567890\",\"USER\":\"0987654321\",\"STATUS\":20,\"Restkontingent\":null,\"RESULT\":[{\"Login\":\"Benutzerdaten sind korrekt\"}]}"

Define Login.login

#JSON = 0

If ParseJSON(#JSON, Result)
  ExtractJSONStructure(JSONValue(#JSON), @Login, login)
  MessageRequester("(CheckLoginData 2)" + Chr(10) + Login\STATUS + Chr(10) + Login\RESULT()\Login)
  FreeJSON(#JSON)
EndIf

Re: Reading JSON String from structure

Posted: Sat Jun 20, 2020 10:19 am
by menschmarkus
Peter wrote:Your JSON and structure seem to be OK:
Thank you for checking Peter.I am wondering why this error happens the first time only. As soon I repeat the procedure the structure is filled correctly. I prefer to unerstand what happens.
I go on trying to find out what happens. I will write my comment here.If someone knows something, please post ithere.

Re: Reading JSON String from structure

Posted: Sat Jun 20, 2020 2:37 pm
by Paul
menschmarkus wrote:I will write my comment here. If someone knows something, please post it there.
The code I posted works fine so if your code is the same and does not work, you either have more code that you are not telling us about and it is causing the problem or the communication with your Server/Server Code is an issue.

Re: Reading JSON String from structure

Posted: Sun Jun 21, 2020 11:14 am
by menschmarkus
Paul wrote:
menschmarkus wrote:I will write my comment here. If someone knows something, please post it there.
The code I posted works fine so if your code is the same and does not work, you either have more code that you are not telling us about and it is causing the problem or the communication with your Server/Server Code is an issue.
OK, the complete Code is too large. Here the essential part which Shows the delay effect

Content of Parameter file to load from Client side:

Code: Select all

ky=4264b1257f97f8c65484edc2
ow=0987654321
id=1234567890
pw=passwort
ncon=0
wz=0
fi=0
ph=0
al=60
SB Code:

Code: Select all

#LoginFile = 0
#RegisterWindow = 0
#Button_OpenFile = 0
Structure register
  key.s
  ID.s
  owner.s
  Passw.s
  status.i
  loginstatus.i
  wz.i          
  fi.i          
  phon.i        
  qual.i        
  al.i          
  ad.s          
  nm.s          
  ncon.i        
EndStructure
Structure slogin
  Login.s
EndStructure
Structure login
  Owner.s
  USER.s
  STATUS.i
  List RESULT.slogin()
EndStructure

Global Login.login
Global NewMap parameter.register()

Declare ChooseFile()
Declare LeftClickHandler()
Declare ReadFileParameter(status.i,Filename.s,File.i,size.i)
Declare ReadLoginFile()
Declare runRegisterWindow()

Procedure runRegisterWindow()
OpenWindow(#RegisterWindow,#PB_Ignore,#PB_Ignore,320,190,"Anmeldung",#PB_Window_ScreenCentered) 
ButtonGadget(#Button_OpenFile,10,150,300,30,"Lade Startdatei") 
EndProcedure 
Procedure ChooseFile()
  If NextSelectedFile()
    OpenFile(#LoginFile,SelectedFileID(),@ReadFileParameter(),#PB_LocalFile)
  Else
    MessageRequester("konnte Datei " + Chr(34) + SelectedFileName() + Chr(34) + " nicht öffnen")
  EndIf
EndProcedure
Procedure LeftClickHandler()
  Select GetActiveGadget()
    Case #Button_OpenFile                                                      
      ReadLoginFile()
      Debug parameter("0")\owner
      Debug parameter("0")\ID
EndSelect
EndProcedure
Procedure ReadFileParameter(status.i,FileName.s,File.i,size.i)
  Protected ReadLine.s 
    While Not Eof(File)
      ReadLine = ReadString(File)  
      Select UCase(Left(ReadLine,2))
        Case "OW"
          parameter("0")\owner = StringField(ReadLine,2,"=")
        Case "ID"
          parameter("0")\ID = StringField(ReadLine,2,"=")
        Case "PW"
          parameter("0")\Passw = StringField(ReadLine,2,"=")
        Case "AL"
          parameter("0")\al = Val(StringField(ReadLine,2,"="))
        Case "FI"
          parameter("0")\fi = Val(StringField(ReadLine,2,"="))
        Case "PH"
          parameter("0")\phon = Val(StringField(ReadLine,2,"="))
        Case "WZ"
          parameter("0")\wz = Val(StringField(ReadLine,2,"="))
        Case "KY"
          parameter("0")\key = StringField(ReadLine,2,"=")
        Case "NCON"
          parameter("0")\ncon = Val(StringField(ReadLine,2,"="))
          parameter("0")\qual = parameter("0")\ncon
      EndSelect
    Wend
    CloseFile(file)                                                          
EndProcedure
Procedure ReadLoginFile()
  OpenFileRequester("*.par|*.par",@ChooseFile())
EndProcedure

BindEvent(#PB_Event_LeftClick,@LeftClickHandler())

runRegisterWindow()
ReadLoginFile()
After first call of Event the debugged values are still undefined. As soon the second call is done the values are correct
This is strange to me. This is a sample of Data from a File. The same happene if I do a HTTPRequest !