Javascript access to Contact/Member/Event data
I would love to have data available to JavaScript that can be used to access other contact, membership, or event data that may not be available on a page or widget.
For instance, I have a case where I need to display links based on whether they belong to a certain membership group or membership level.
There is some 'BONAPAGE' global variables that can be accessed for system or page view status but nothing for the record of the current screen you may be viewing.
It would be great if there was a global object(s) available that contained the current record set just like the JSON data you can get from the API. So you could access 'contact.ismember' for example.
Please post your thumbs up so we can get this in a release.
Public API is now available for javascript access by path http://your_account.wildapricot.org/sys/api/….
This means that:
- AJAX requests to API is in the same domain
*JS application is able to access API without token - AJAX requests directed to the same domain as
- JS access API with the same permissions as currently logged in user.
Please read more on help site:
http://help.wildapricot.com/display/DOC/Authenticating+API+access+from+a+Wild+Apricot+site+page
-
Rick Smith commented
Hi Dmitry,
No matter what I try I can not do updates with the new API. Your code or mine. My code works perfect with the old API but same code will not with the new API. What am I missing ?
What determines the permissions for the API ? Is something preventing me from doing Updates ? Reads are fine.
The new API operates in the permission context of the logged on user so will I be able to make a page accessible to regular members where they can edit or cancel registrations via the API ? The API is capable. Will the logged in member have permission ?
Is this the correct medium for handling this ?
-
Rick Smith commented
Hi Dmitry,
There is nothing in the response body. Empty, blank.
I am in the IE console where I can inspect Request/Response Header, Body, etc
I just get 400 and nothing. The only message I can see is Bad Request.
-
Dmitry Smirnov commented
Rick,
When api returns 400, it also send error explanation in response body. You can find the details in browser console.
-
Rick Smith commented
Hi Dmitry,
I got the sample to work and the Who am I link is OK. I don't have a problem with read
I recreated the sample on my site, and the create contact link gives me the same 400 Bad Request error. Code is below
Is something not authorized right ? My login is the site admin ?
<div class="WaGadgetLast WaGadgetCustomHTML gadgetStyleNone" id="id_TDkdZIQ">
<div class="gadgetStyleBody">
<div>
<a name="whoAmI" id="whoAmI" href="#">Who am I?</a><br>
<a name="createContact" id="createContact" href="#">Create new contact</a>
</div>
</div>
</div><script type="text/javascript">try {
var clientId = "ndas7a2c11";
$(document).ready(function(){
var api = new WApublicApi(clientId);
api.init();$("#whoAmI").click(function(){
api.apiRequest({
apiUrl: api.apiUrls.me(),
success: function (data, textStatus, jqXhr) {
alert("Hello " + data.FirstName + " " + data.LastName + " !\r\nSpirits say that your ID is '" + data.Id + "' and your email is '" + data.Email + "'."); }
});
});
$("#createContact").click(function(){
api.apiRequest({
apiUrl: api.apiUrls.contacts(),
method: "POST",
data: { email: "user" + Math.floor(Date.now() / 1000) + "@invaliddomain.com"},
success: function(data, textStatus, jqXhr){
alert("New contact #" + data.Id + " with email " + data.Email + "was successfully created");
},
error: function(data, textStatus, jqXhr){
alert("Failed to create new contact. See console for details");
}
});
});
});
} catch(e) {}</script> -
Dmitry Smirnov commented
Yes, you should be logged in. Just apply for free membership and log in.
First link works for any authenticated user. Second one works only for admins, but you still can view page source code.
-
Rick Smith commented
Hi Dmitry,
I did look at the sample but clicking on the links did not do anything. Wouldn't we need to be logged in to that site ? What is the login ?
-
Dmitry Smirnov commented
Rick,
Could you please take a look at http://houseofbamboo.wildapricot.org/JS-sample. On that page you will find a link "create new contact" and valid JS code.
Steve,
Wild apricot system experienced temporary connectivity issues (https://forums.wildapricot.com/forums/308923-service-notices/suggestions/13061973-intermittent-connectivity-issues). Currently the system works fine.
Your code looks valid.
-
Rick Smith commented
Is the public API fully functioning now ? I am getting 400 Bad Request on any Put/Post. There is no further info available.
As far as I can tell everything is as it should be ??
Ajax call:
rest = $.ajax({
type: "PUT",
url: url,
headers: { "clientId": WAclientId}, //V2.0
//headers: { Authorization:'Bearer ' + token},
datatype: "json",
cache: false,
async: false,
data: data
});
rest.done( function (rdata,stat) {
dwrite("Post Status: " + rest.status);
dwrite("Status Text: " +rest.statusText);
dwrite("Response Text: " +rest.responseText);
dwrite("Ready State: " +rest.readyState);
//return rest;
return rdata;
});Please advise
-
Steve Riegel commented
Seemed to work once or twice for me today, before WA sitewide intermittent connectivity issues began (shown under Service Notices)
Getting 503 service unavailable errors now for <mysite>/sys/api calls.
Are such calls causing the WA-wide intermittent connectivity problems?
My code (just populates a field with the current member id):
/* who am i? */
var api = new WApublicApi(clientId);
$.when(api.init()).done(function(){
api.apiRequest({
apiUrl: api.apiUrls.me(),
success: function(data, textStatus, jqXhr) {$("#rmemb").val(data.Id);},
error: function(jqXHR, textStatus, errorThrown) {
$("#rmemb").val("error");
$("#notes").val(textStatus + " (" + jqXHR.status + ") : " + errorThrown);
}
})
}); -
The issue is fixed, both GET and POST works. Demo code is here: http://houseofbamboo.wildapricot.org/JS-sample
-
Rick Smith commented
Good News. Thanks Wildapricot Team
-
Dmitry Smirnov commented
We have found a solution for both issues (GET and POST requests). A fix is expected to be published by Monday.
-
Rick Smith commented
Hi Dmitry,
Now it is doing the 302 rediredt to logon.aspx on GET as well.
Am I doing something wrong in the authentication ? Is Something missing ?
Thanks for your help and support
-
Rick Smith commented
Thanks Dmitry. Is this unique to us ?
The new API basically can not be used until we find a solution. If it is not just isolated to us, then nobody could use it
-
Dmitry Smirnov commented
Hi Rick,
I have reproduced the issue. I think it's a bug but currently I can't say haw fast we can fix it.
FYI I have implemented a helper class to work with API. It can be found here: https://github.com/WildApricot/ApiSamples/blob/master/JavaScript/waPublicApi.js
-
Rick Smith commented
Hi Dmitry,
Here is what is happening:
1. The POST request is made using the /sys/api URL
2. The POST returns a code 302 with a redirect URL and the original URL as a parameter
3. The browser automatically redirects to the URL from above
4. The redirect URL is http://choice.agingmissouri.org/login.aspx
This is supposed to be a login page ?
The URL does not exist so 404 is returned with the 404 page HTMLThere is no login.aspx ?
This is similar to single sign-on behavior. In SSO after a good login, it is redirected again back to original URL.Since we are local/same domain, we are supposed to be authenticated with the ClientID. Why is it trying to get a login ?
Maybe the POST/PUT Functions are not recognizing the ClientID and looking for the token per 'External Authentication'.
I checked the APP authorization and it is set to full access
Let me know
-
Rick Smith commented
Dmitry,
Correction: the 'data = JSON.parse(js(data));' line in the second set of code is not part of the normal code. It was an attempt to stringify then parse the data to see if that would help.
-
Rick Smith commented
Hi Dmitry,
Here is the code used to post data.
Original Code (Old token way)
function postData(data, url, token){
dwrite("Updating - " + url);
dwrite("Posting- Data:" + js(data));
rest = jQuery.ajax({
type: "POST",
url: url,
headers: { Authorization:'Bearer ' + token }, // This is the old auth way
datatype: "json",
async: false,
data: data
});
rest.done( function(data,rest) {
dwrite("Post Status: " + rest.status);
dwrite("Status Text: " +rest.statusText);
dwrite("Response Text: " +rest.responseText);
dwrite("Ready State: " +rest.readyState);
return ;});
}This code works beautiful. I call it from all other functions. The calling functions supplies the url and the properly formatted JSON data which determines what we are putting.
Here is the new code. The only change is the authorization header.
function postData(data, url, token){
dwrite("Updating - " + url);
dwrite("Posting- Data:" + js(data));
data = JSON.parse(js(data));
alert("Post Data: data=" + js(data));
rest = jQuery.ajax({
type: "POST",
url: url,
headers: { "clientId": token}, //V2.0 Token = clientID
datatype: "json",
async: false,
data: data
});
rest.done( function(data,rest) {
dwrite("Post Status: " + rest.status);
dwrite("Status Text: " +rest.statusText);
dwrite("Response Text: " +rest.responseText);
dwrite("Ready State: " +rest.readyState);
return ;});
}
This code, via the /sys/api/ URL errors with the 404. The same data is passed and it does not accept it. The get code is identical except for GET.
(Wow - I should have one function and pass GET,POST,PUT as another parameter. Sweet!)
I suspect it is a JSON format issue as well like the GET was. I had to add a JSON.parse(data) to the returned JSON from the GET.
What I could find on the Web was the format the data was in was a JSON 'String' rather than a JSON object. JSON.parse parses a string into a JSON object.
I tried stringifying the POST data but it was no help.
The GET data looked like this:
\"[{\"Id\":11280,\"statName}]\"Which cannot be manipulated as JSON. The article I found mentioned double serializing ?
Is the something similar happening with the POST ?
Are you using a different server or code for the /sys/api URL ? Is any one else successfully using the new method?This is my last hurdle and I can be fully implemented with the New API.
We are excited because it is not only faster, but we can access pages with API function now from any browser without having to only use IE set to ignore cross-domain, and we can now add custom functions to the public member pages as they also do not have to have a special browser setup.The code change for this was minimal. Mostly just skipping the Auth/Get Token function.
Major Kudos for this undertaking.
-
Hi Rick,
could you please share a code, which demonstrates both issues?
Dmitry
-
Rick Smith commented
I am working on the new API using a local path. Easy swith from previous method and works like a charm mostly. It also seems much faster. Excellent!
I did have an issue with data from GET. The returned JSON was actually a JSON string instead of a JSON object. The data return was 'Escaped' and had \in front of all { and [.
I used the same code the fetch the data using the new ClientID authentication but got the different data.
I got around this by doing a JSON.parse on the returned data and back in business. Simple change and I have separate code sets anyway right now.
Reading data with that simple change works like a champ.
My last issue is writing data back. Again same code just changing the AUTH header, when I try to Post I am getting a code 404. The code table says
404
The resource you are trying to access either does not exist or is not available.
Any ideas ? Anyone else using the API with the new authentication ?