Parsing JSON into AGOL as attribute data

2017
7
11-21-2017 06:56 AM
by Anonymous User
Not applicable

Does anyone have any experience (maybe using arcade?) to bring in a JSON feed into a web-map to populate a popup.

I have a non-GeoJSON feed of user data I would like to use to create a popup for a campus style map.

The feed would come from a url like : https://directory.com/api/user?account=1234

and would look something like:

{
   "cn":"Smith, John",
   "title":"Specialist",
   "mail":"Username@email.com",
   "department":"GIS",
   "telephoneNumber":"+1 416-967-1111 ext. 1234"
}

Is the only way to do this to bring the app local and write custom JS for it?

Tags (2)
0 Kudos
7 Replies
GavinRehkemper
Esri Contributor

Joel, I would like some clarification - is the JSON in one of the attribute columns of your data? Or do you want to make a dynamic API call to https://directory.com/api/user?account={ACCOUNT_NUMBER_FROM_ATTRIBUTES} when the user clicks on the feature?

by Anonymous User
Not applicable

A dynamic call when the user click the feature

0 Kudos
GavinRehkemper
Esri Contributor

Ok. I am not aware of a way to make a dynamic API request using Arcade. Maybe someone else will have other ideas, but here are a few:

  • One idea would be to use Esri Koop (you would probably need to create a custom Provider) to add your API data to your Feature Service as additional attribute columns.
  • Another option would be, as you mentioned, to write a custom JavaScript web application or Web AppBuilder widget that makes the dynamic API request when the feature is clicked.
KellyGerrow
Esri Frequent Contributor

Hey Joel,

Are you looking to add the information to a feature service? If so, you can bring some of this information into a hosted pop up. ArcGIS Online pop ups support the following specific html tags and attributes but not custom code:

Supported HTML—ArcGIS Online Help | ArcGIS 

It sounds like you are looking to have the pop up send a request and read the data from an external source which will require custom coding and hosting.

Here is a link to an old blog about customizing pop ups with the JSAPI: Making Your Pop-up Pop! | ArcGIS Blog 

Current pop up doc:

Intro to PopupTemplate | ArcGIS API for JavaScript 4.5 

-Kelly

XanderBakker
Esri Esteemed Contributor

We had a similar challenge for a client that used the Campus App, but we went for a Python script that updates the related table based on values from the active directory. You could schedule the task to run for instance each night, but changes made during the day will not be reflected the same day.

0 Kudos
by Anonymous User
Not applicable

I would be very interested to see this script, any chance you would be able to share it?

0 Kudos
XanderBakker
Esri Esteemed Contributor

It contains very specific code for a particular client, but you should be able to tweak it to your needs. It will require you to install win32com:

def main():
    import arceditor
    import arcpy
    import win32com.client
    name_resolver = win32com.client.Dispatch(dispatch='NameTranslate')

    # llenar tabla
    tbl = r"D:\Xander\Campus\gdb\myData.gdb\EmployeeInfo"

    dct_fld_ldap = {'FIRSTNAME':'givenName',
                    'LASTNAME':'sn',
                    'KNOWNAS':'displayName',
                    'COSTCTR': 'departmentNumber',
                    'COSTCTRN':'department',
                    'EMAIL':'mail',
                    'EXTENSION':'telephoneNumber',
                    'BUILDING':'physicalDeliveryOfficeName',
                    'FLOOR':'location',
                    'LOCATION':'location',
                    'USERTYPE':'title',
                    'JEFE':'manager',
                    'TELEFONO':'telephoneNumber',
                    'DIRECCION':'streetAddress',
                    'DocumentID':'employeeID',
                    'photoURL': 'employeeID',
                    'employeeNumber':'employeeNumber',
                    'WinLogin':'uid',
                    'uidNumber': 'uidNumber'}

    special = ['COSTCTR','EXTENSION','FLOOR','JEFE','photoURL']
    users = ['login name 1', 'login name 2', 'login name 3', 'etc']

    cnt_tot = len(users)
    dct_tot = {}
    numeric_fields = ['COSTCTR', 'EXTENSION', 'FLOOR', 'employeeNumber', 'uidNumber']

    flds = dct_fld_ldap.keys()
    print flds

    users_skipped = []
    cnt = 0
    with arcpy.da.InsertCursor(tbl, flds) as curs:
        for user in users:
            cnt += 1
            if cnt % 100 == 0:
                print "Processing user {0} de {1}".format(cnt, cnt_tot)
            try:
                name_resolver.Set(3, 'domainname\{0}'.format(user))
                ldap_query = 'LDAP://{}'.format(name_resolver.Get(1))
                ldap = win32com.client.GetObject(ldap_query)

                # crear row
                r = []
                for fld in flds:
                    att = dct_fld_ldap[fld]
                    info = getInfo(ldap, att)
                    if info != '':
                        if fld in special:
                            if fld == 'COSTCTR':
                                try:
                                    val = info[-4:]
                                    result = int(val)
                                except:
                                    result = -999
                            if fld == 'EXTENSION':
                                try:
                                    val = info[-4:]
                                    result = int(val)
                                except:
                                    result = -999
                            if fld == 'FLOOR':
                                try:
                                    val = info[:2]
                                    result = int(val)
                                except:
                                    result = -9
                            if fld == 'JEFE':
                                try:
                                    lista = info.split(',')
                                    a = lista[0]
                                    result = a.replace('CN=','')
                                except:
                                    result = "DESCONOCIDO"
                            if fld == 'photoURL':
                                # generar URL con id:
                                cc = str(info)
                                result = 'https://internal url to page with fotos of employees {0}.jpg'.format(cc)
                        else:
                            result = info
                    else:
                        if fld == 'photoURL':
                            result = 'http://image in case no foto available .png'
                        elif fld in numeric_fields:
                            result = 0
                        else:
                            result = ''
                    r.append(result)
                print r
                row = tuple(r)
                curs.insertRow(row)

            except:
                users_skipped.append(user)

    print "\nskipped users:"
    for user in users_skipped:
        print user



def getInfo(ldap, att):
    try:
        return ldap.Get(att)
    except:
        return ''


if __name__ == '__main__':
    main()
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

As an alternative you could also use the library found here: Tim Golden's Python Stuff: active_directory or simply connecting to your URL to obtain the info by using the library requests.