After looking at several questions/answers here, I'm not seeing what I think I need. I have a page posting to an asp server page via ajax. The returning json string is showing up in the console on Firefox. I can see the post data going to the asp page, I can see the response which is
{ "firstname": "Christopher","lastname": "Romero","email": "cromero#marketscout.com","adminlvl": "00","message": "Thanks for logging in!" }
I can also see the values of the string above in the JSON tab in Console --> ALL --> JSON. There are no errors being reported inside the console. Here is my javascript:
$('#loginsub').click(function() {
$.ajax({
url: "logincheck.asp",
type: "POST",
data: $('#loginform').serialize(),
dataType: "json",
success: function(data) {
console.log(data);
//alert(data.firstname + ' ' + data.lastname);
//alert(data[0].firstname + ' ' + data[0].lastname);
$.trim(data);
var json = $.parseJSON(data);
alert(json.firstname);
}
});
});
Here is the asp that is running on the server on logincheck.asp:
set cmd = Server.CreateObject("ADODB.Command")
with cmd
.ActiveConnection = cnnopen
.CommandText = storedproc
.CommandType = adCmdStoredProc
dim intCount,intItem
for each item in odcformdata
select case vartype(odcformdata(item)) 'this is searching for the correct data type to put into the parameter [type] argument below. (integers, currency, dates, & strings)
case 2 : .Parameters.Append .CreateParameter("#"&cstr(item),adInteger,adParamInput,len(odcformdata(item)),odcformdata(item))
case 6 : .Parameters.Append .CreateParameter("#"&cstr(item),adCurrency,adParamInput,len(odcformdata(item)),odcformdata(item))
case 7 : .Parameters.Append .CreateParameter("#"&cstr(item),adDate,adParamInput,len(odcformdata(item)),odcformdata(item))
case 8 : .Parameters.Append .CreateParameter("#"&cstr(item),adVarChar,adParamInput,len(odcformdata(item)),odcformdata(item))
end select
next
end with
set rs = cmd.execute
'do stuff with returned results from select or leave blank if insert/delete/etc stored procedure
if rs.EOF = false then
'Build json array based on fields returned from stored proc.
dim arrJSON
arrJSON = "{ "
while not rs.EOF
for each fields in rs.Fields
arrJSON = arrJSON & """" & fields.name & """: """ & fields & ""","
next
rs.movenext
wend
arrJSON = arrJSON & """message"": ""Thanks for logging in!"","
arrJSON = left(arrJSON, len(arrJSON)-1) & " }"
response.write arrJSON
end if
set rs = nothing
set cmd = nothing
odcformdata.removeall
The alerts() in the javascript are not returning values that I would expect, I'm getting [object Object] returning on the alert when I'm expecting the JSON array/string to get printed out.
Anyone with some advice for me? I'm a jquery rookie and getting better, but this is getting on my nerves!
What does your first console.log(data) show?
This works for me:
http://jsfiddle.net/2tvCf/
Related
I am using QTP/UFT for automating my UI application. I would like to compare the UI values with the values from the REST API response. I'm new to VBScript and I have coded the method to call the REST API and get the response but i'm trying to find a solution how to parse the JSON using VBScript.
Please help me how i could parse the json response? (Code below)
OR if it's easier to accept the REST response in xml and parse it in VBS?
Appreciate your help and ideas. Thanks!
userName = "abc#xyz.com"
password = "blah.123"
acctNumber = "01999994201"
URL1="https://CXaic-blah.blah.ocp.blah.com:243/ic/api/integration/v1/flows/rest/blah_ACCNTSEARCH/1.0/accountSearch?accountNumber="
URL=URL1&acctNumber
Set objXmlHttpMain = CreateObject("Msxml2.ServerXMLHTTP")
on error resume next
objXmlHttpMain.open "GET",URL, False , userName, password
objXmlHttpMain.setRequestHeader "Accept", "application/json"
objXmlHttpMain.setRequestHeader "charset", "UTF-8"
objXmlHttpMain.send
restjsonresp = objXmlHttpMain.responseText
Below is the format of the json response i get:
{
"searchResponse":{
"element":[
{
"accType":"R",
"accountNumber":"1111111",
"accountStatus":"A",
"taxId":""
}
]
}
}
While I don't have QTP/UFT to test or verify the following code, I offer-up these JSON parsing solutions as-is for experimentation...
1) Inject a JScript block into a "htmlfile" object
Dim y, html : Set html = CreateObject("htmlfile")
Dim window : Set window = html.parentWindow
window.execScript "var json=" & restjsonresp & ";var e=new Enumerator(json.searchResponse.element);", "JScript"
While Not window.e.atEnd()
Set y = window.e.item()
Print "acctType: " & y.accType
Print "accountNumber: " & y.accountNumber
Print "accountStatus: " & y.accountStatus
Print "taxId: " & y.taxId
window.e.moveNext
Wend
2) Calling JScript code using the "MSScriptControl.ScriptControl" (requires 32-bit)
Dim x, eng : Set eng = CreateObject("MSScriptControl.ScriptControl")
eng.Language = "JScript"
eng.AddCode "function json() { return " & restjsonresp & "; }"
Dim oResp : Set oResp = eng.Run("json")
For Each x In oResp.searchResponse.element
Print "acctType: " & x.accType
Print "accountNumber: " & x.accountNumber
Print "accountStatus: " & x.accountStatus
Print "taxId: " & x.taxId
Next
3) Injecting a JScript block into "InternetExplorer.Application" (overkill? perfomance hit)
Dim z, objIE : Set objIE = CreateObject("InternetExplorer.Application")
objIE.Navigate2 "about:blank"
objIE.Toolbar = False
objIE.StatusBar = False
objIE.MenuBar = False
Do While objIE.Busy
Wait 1
Loop
objIE.Visible = False
objIE.document.open "text/html"
objIE.document.write "<script type='text/javascript'>document.json=" & restjsonresp & ";document.jsonEnum = new Enumerator(document.json.searchResponse.element);</script>"
objIE.document.close
While Not objIE.document.jsonEnum.atEnd()
Set z = objIE.document.jsonEnum.item()
Print "acctType: " & z.accType
Print "accountNumber: " & z.accountNumber
Print "accountStatus: " & z.accountStatus
Print "taxId: " & z.taxId
objIE.document.jsonEnum.moveNext
Wend
objIE.Quit
4) Using Demon's VbsJson object (a pure VBScript solution; albeit, with more code)
https://github.com/eklam/VbsJson
5) Use regular expressions (only for simple, well-defined JSON responses)
Dim re : Set re = New RegExp
re.IgnoreCase = True
re.Pattern = "\{\s*""searchResponse""\s*\:\s*\{\s*""element""\s*\:\s*\[\s*(\{\s*""accType""\s*\:\s*""(.*)""\s*,\s*""accountNumber""\s*\:\s*""(.*)""\s*,\s*""accountStatus""\s*\:\s*""(.*)""\s*,\s*""taxId""\s*\:\s*""(.*)""\s*\})\s*\]\s*\}\s*\}"
If re.Test(restjsonresp) Then
Dim matches : Set matches = re.Execute(restjsonresp)
Print "acctType: " & matches(0).SubMatches(1)
Print "accountNumber: " & matches(0).SubMatches(2)
Print "accountStatus: " & matches(0).SubMatches(3)
Print "taxId: " & matches(0).SubMatches(4)
End If
6) Convert JSON to XML, then parse the XML (lots of code, potential overkill)
https://github.com/pravynandas/JSONToXML
If you can control the response, and deliver XML instead of JSON, then it may be preferable to stick with XML for VBScript in QTP/UFT. Regardless, I hope something here is helpful.
Enjoy.
I have been trying to find a way to extract rows of data from an SQL database, format the returned rows into a JSON format and post/send that to a JSON web API. I am using an asp JSON serializer for VBScript (.Flush) to transform the SQL data into JSON. It works great, I have the structure i need and I also have the method to send the JSON formatted data. So what's the issue you might ask.....
The issue is I can't send apiDefaults.flush to the webserver, it does not work. If I send the same data as a hardcoded variable it works perfectly and the API takes the data.
Let me explain some more.
Here is the JSON output I see on screen using apiDefaults.flush This is perfectly formatted exactly what i need.
{"authentication": { "apiKey": "123456789101112131415" }, "createProperties": [ { "name": "Property 1", "propKey": "6sf3zqq151n2wkah" }, { "name": "Property 2", "propKey": "yuf38zc4cls9hz19" } ] }
However, I can't get this value stored into a variable. If I could simply do the following, my issue would be resolved but you can't bind a the .flush method to a variable?!?! I don't understand why as it is just a string of text in theory.
dim myJson = apiDefaults.flush
This bit of code here is where I set the values to send to the web server, my variable that holds the JSON string
'IF I USE THIS IT WORKS PERFECTLY, IT TAKES MY MANUALLY CREATED VARIABLE/STRING AND SENDS IT
oXMLHttp.send strmultiprop
'THIS IS WHAT I FIGURED I SHOULD BE ABLE TO USE BUT IT IS NOT TREATED LIKE A VARIABLE
oXMLHttp.send apiDefaults.flush
' I TRIED THIS AND THIS WON'T WORK EITHER
oXMLHttp.send myJson
Below is my actual scripts
<% #LANGUAGE="VBSCRIPT" CODEPAGE="65001" %>
<!--#include file="JSON_2.0.4.asp"-->
<%
Function QueryToJSON(dbcomm, params)
Dim rs, jsa, aaa, bbb
Set rs = dbcomm.Execute(,params,1)
Set jsa = jsArray()
Do While Not (rs.EOF Or rs.BOF)
Set jsa(Null) = jsObject()
For Each col In rs.Fields
jsa(Null)(col.Name) = col.Value
Next
rs.MoveNext
Loop
Set QueryToJSON = jsa
rs.Close
End Function
strConn = "PROVIDER=SQLOLEDB;DATA SOURCE=LOCALHOST;UID=sa;PWD=********;DATABASE=DB_Site"
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open strConn
query = "SELECT wce_uid as name, uniqueid as propKey FROM wces_users WHERE Prop_Moved = ?"
CustomerID = "Y" 'Request.QueryString("CustomerID")
arParams = array(CustomerID)
Set cmd = Server.CreateObject("ADODB.Command")
cmd.CommandText = query
Set cmd.ActiveConnection = conn
' https://stackoverflow.com/questions/40781130/setting-up-rest-api-in-classic-asp
key = "1234567891011121314151678910"
url = "https://www.beds24.com/api/json/createProperties"
'1 PROPERTY WORKING
str1prop = "{""authentication"": { ""apiKey"": ""123456789101112131415"" }, ""createProperties"": [ { ""name"": ""New Test"", ""propKey"": ""NewTest1"" } ] }"
'2 PROPERTY WORKING
strmultiprop = "{""authentication"": { ""apiKey"": ""123456789101112131415"" }, ""createProperties"": [ { ""name"": ""3333"", ""propKey"": ""3333"" }, { ""name"": ""4444"", ""propKey"": ""4444"" } ] }"
set apiDefaults = QueryToJSON(cmd, arParams)
'3 THE FLUSH METHOD --- THIS DOES NOT SET THE VRIABLE TO THE OUTPUT I SEE ON SCREEN
dim myJson = apiDefaults.flush
apiDefaults.flush
conn.Close : Set Conn = Nothing
Dim oXMLHttp
Set oXMLHttp=Server.Createobject("MSXML2.ServerXMLHTTP.6.0")
oXMLHttp.open "POST", url,false
oXMLHttp.setRequestHeader "Content-Type", "application/json"
oXMLHttp.send apiDefaults.flush 'THIS IS THE ISSUE LINE USING THIS. if I CHANGE TO strmultiprop NO ISSUES AT ALL.
response.write oXMLHttp.responseText
Set oXMLHttp = Nothing
%>
Any advice on this would be great.
Thanks for looking.
My question was answered by #SearchAndResQ
"Try oXMLHttp.send apiDefaults.jsString, you need the value in that property"
I am trying to write VBA to post json to an api and parse the results into a worksheet. I can generate the JSON and am confident I can parse the result into what I need.
I know there are online tools to convert json to vba and back and browser add ins to post requests but I am the only one in the office that can do this so if I'm sick or on leave I would like to automate it. To do that I need to send the json and maybe store the response so I can parse it.
I'm new to coding so posting a request like this is over my head.
So far I have the following code to write the json. I would appreciate any help in getting me started. If needed I can post a sample of the json or the api I would like to post it to.
Apologies for the poor code I know I can improve it but want to get the json response as I think it will be the most challenging part.
EDIT Have made some progress. Can now send a JSON string to the URL and get the response. However it is always returning a failure:
"{
""message"": ""An error has occurred.""
}"
If I manually send the json with httpRequestor the result is returned correctly.
This seems to suggest that somewhere in the code the JSON is getting mixed up or modified somehow when it is being posted.
Updated code below. (Have removed any reference to actual data)
EDIT 2 fixed and working.
Removed quotes from
objHTTP.send ("Json")
Private Sub CommandButton21_Click()
Dim h_1 As String
Dim h_2 As String
h_1 = Range("A1")
h_2 = Range("B1")
h_3 = Range("C1")
h_4 = Range("D1")
h_5 = Range("E1")
h_6 = Range("F1")
sv_1 = 2
sv_2 = 2
sv_3 = 2
sv_4 = 2
sv_5 = 2
sv_6 = 2
For f = 15 To 21
v_1 = Range("A" & sv_1)
v_2 = Range("B" & sv_2)
v_3 = Range("C" & sv_3)
v_4 = Range("D" & sv_4)
v_5 = Range("E" & sv_5)
v_6 = Range("F" & sv_6)
y = "[{""" & h_1 & """:""" & v_1 & """,""" & h_2 & """:""" & v_2 & """,""" & h_3 & """:""" & v_3 & """,""" & h_4 & """:""" & v_4 & """,""" & h_5 & """:""" & v_5 & """,""" & h_6 & """:""" & v_6 & """ }]"
Range("A" & f).Value = y
sv_1 = sv_1 + 1
sv_2 = sv_2 + 1
sv_3 = sv_3 + 1
sv_4 = sv_4 + 1
sv_5 = sv_5 + 1
sv_6 = sv_6 + 1
Next f
Dim objHTTP As Object
Dim Json As String
Json = Range("A15")
Dim result As String
'Set objIE = CreateObject("InternetExplorer.Application") ' Don't think this is needed
'objIE.navigate "about:blank" ' Don't think this is needed
'objIE.Visible = False ' Don't think this is needed
Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")
URl = "http://myApi/iSendJsonTo"
objHTTP.Open "POST", URl, False
'objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
objHTTP.setRequestHeader "Content-type", "application/json"
objHTTP.send ("Json")
result = objHTTP.responseText
'objIE.document.Write result ' Don't think this is needed
'Some simple debugging
Range("A25").Value = result
Range("A26").Value = Json
Set objHTTP = Nothing
Here is the code that is sending the JSON, cleaned up a little.
Dim objHTTP As Object
Dim Json As String
Json = Range("A15") 'here I am pulling in an existing json string to test it. String is created in other VBA code
Dim result As String
Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")
URl = "http://myApi/iSendJsonto/"
objHTTP.Open "POST", URl, False
objHTTP.setRequestHeader "Content-type", "application/json"
objHTTP.send (Json)
result = objHTTP.responseText
'Some simple debugging
Range("A25").Value = result
Range("A26").Value = Json
Set objHTTP = Nothing
I am trying to build Excel page from iTunes query data.
An example for Angry Birds app my query would look like:
https://itunes.apple.com/lookup?id=343200656&country=AL checking Albania iTunes
https://itunes.apple.com/lookup?id=343200656&country=DZ checking Algeria iTunes
... 150 more stores
My question is the most efficient way to do this query and parse response.
I only know how to to xmlhttp query. Please enlighten me as the better way to do this.
I have read some documentation for VB-JSON, Json.net, CDataSet, fastJSON, but cannot figure out how to get started trying those tools. Anyone have more VBA code examples pulling JSON or way to explain usage of these frameworks to a newb?
Dim innerHTML As Object
Dim myText As String
JsonCheck = ""
Set innerHTML = CreateObject("Microsoft.XMLHTTP")
With innerHTML
.Open "GET", iTunesAPI_link, False
.send
myText = .responsetext
End With
Set innerHTML = Nothing
If InStr(myText, ":0") = 20 Then 'no results found
result = "Down"
ElseIf InStr(myText, "Your request produced an error.") = 46 Then 'link error
result = HTMLCheck(human iTunes link)
Else 'found the app
result = call function which parses myText for desired fields
Endif
Here's a basic approach using the scriptcontrol:
Sub Tester()
Dim json As String
Dim sc As Object
Dim o
Set sc = CreateObject("scriptcontrol")
sc.Language = "JScript"
json = HttpGet("https://itunes.apple.com/lookup?id=343200656&country=AL")
'some json property names may be keywords in VBA, so replace with
' something similar....
json = Replace(json, """description""", """description_r""")
Debug.Print json
sc.Eval "var obj=(" & json & ")" 'evaluate the json response
'add some accessor functions
sc.AddCode "function getResultCount(){return obj.resultCount;}"
sc.AddCode "function getResult(i){return obj.results[i];}"
Debug.Print sc.Run("getResultCount")
Set o = sc.Run("getResult", 0)
Debug.Print o.kind, o.features, o.description_r
End Sub
Function HttpGet(url As String) As String
Dim oHTML As Object
Set oHTML = CreateObject("Microsoft.XMLHTTP")
With oHTML
.Open "GET", url, False
.send
HttpGet = .responsetext
End With
End Function
There's a worked-out approach in Codo's answer to this question: Excel VBA: Parsed JSON Object Loop
I had a similar issue with querying Salesforce's REST API and found dealing with JSON through ScriptControl ended up being unmanageable. I used the following library for parsing and converting to JSON and it's worked perfectly for me: https://code.google.com/p/vba-json/.
Dim JSON As New JSONLib
Dim Parsed As Object
Set Parsed = JSON.parse(jsonValue)
Debug.Print Parsed("resultCount")
Debug.Print Parsed("results")(0)
Using that library, I then wrapped up some of the common functionality for making web requests that I think would help you out: https://github.com/timhall/Excel-REST
Using these libraries, your code would look something like the following:
Dim iTunesClient As New RestClient
iTunesClient.BaseUrl = "https://itunes.apple.com/"
Dim Request As New RestRequest
Request.Format = json
Request.Resource = "lookup"
Request.AddQuerystringParam "id", "343200656"
Request.AddQuerystringParam "country", "AL"
Dim Response As RestResponse
Set Response = iTunesClient.Execute(Request)
' => GET https://itunes.apple.com/lookup?id=343200656&country=AL
If Response.StatusCode = 200 Then
' Response.Data contains converted JSON Dictionary/Collection
Debug.Print "Result Count: " & Response.Data("resultCount")
Dim i As Integer
For i = LBound(Response.Data("results")) To UBound(Response.Data("results"))
Debug.Print "Result " & i & ": " & Response.Data("results")(i)
Next i
Else
Debug.Print "Error: " & Response.Content
End If
I want to perform a hidden HTTP-GET request from MS-access,
as simple as possible, without any extra libraries/components.
Just a simple declare all needed.
Has WinHttp left the building??
Here is a great page about that.
Hope this helps
Dim xhr As Object
Dim webServiceURL As String
Dim actionType As String
Dim thisRequest As String
Dim targetWord As String
WebServiceURL = "http://services.aonaware.com/DictService/DictService.asmx/"
actionType = "Define?word="
targetWord = "Marketplace"
thisRequest = webServiceURL & actionType & targetWord
'use late binding
Set xhr = CreateObject("Microsoft.XMLHTTP")
xhr.Open "GET", thisRequest, False
xhr.Send
If xhr.status = 200 Then
Debug.Print xhr.responseText
MsgBox xhr.getAllResponseHeaders
Else
MsgBox xhr.status & ": " & xhr.statusText
End If
Set xhr = Nothing