tkf / emacs-request

Request.el -- Easy HTTP request for Emacs Lisp
http://tkf.github.com/emacs-request/
GNU General Public License v3.0
629 stars 93 forks source link

Wrong type argument: listp in github API response #110

Closed azzamsa closed 5 years ago

azzamsa commented 5 years ago

this library help me build my first Emacs package. But now, I am stuck with an error "Wrong type argument: listp".

I try to maka a GET request with the following code

(let* ((archive-response (request "https://api.github.com/notifications?all"
                                    :parser 'json-read
                                    :headers `(("Authorization" . ,(concat "token" " " github-pass))
                                               ("Content-Type" . "application/json"))
                                    :sync t))
         (data (request-response-data archive-response))
         (status (request-response-status-code archive-response)))
    (if (eq status 200)
        data
      404))

The JSON response is

[
    {
        "id": "435117107",
        "unread": true,
        "reason": "mention",
        "updated_at": "2019-02-11T10:41:23Z",
        "last_read_at": "2019-02-10T16:27:56Z",
        "subject": {
            "title": "Add ability to hide article with certain metadata value",
            "url": "https://api.github.com/repos/Pelican-Elegant/elegant/pulls/270",
            "latest_comment_url": "https://api.github.com/repos/Pelican-Elegant/elegant/issues/comments/462283382",
            "type": "PullRequest"
        },
        "repository": {
            "id": 4448119,
            "node_id": "MDEwOlJlcG9zaXRvcnk0NDQ4MTE5",
            "name": "elegant",
            "full_name": "Pelican-Elegant/elegant",
            "private": false,
            "owner": {
                "login": "Pelican-Elegant",
                "id": 45239483,
                "node_id": "MDEyOk9yZ2FuaXphdGlvbjQ1MjM5NDgz",
                "avatar_url": "https://avatars0.githubusercontent.com/u/45239483?v=4",
                "gravatar_id": "",
                "url": "https://api.github.com/users/Pelican-Elegant",
                "html_url": "https://github.com/Pelican-Elegant",
                "followers_url": "https://api.github.com/users/Pelican-Elegant/followers",
                "following_url": "https://api.github.com/users/Pelican-Elegant/following{/other_user}",
                "gists_url": "https://api.github.com/users/Pelican-Elegant/gists{/gist_id}",
                "starred_url": "https://api.github.com/users/Pelican-Elegant/starred{/owner}{/repo}",
                "subscriptions_url": "https://api.github.com/users/Pelican-Elegant/subscriptions",
                "organizations_url": "https://api.github.com/users/Pelican-Elegant/orgs",
                "repos_url": "https://api.github.com/users/Pelican-Elegant/repos",
                "events_url": "https://api.github.com/users/Pelican-Elegant/events{/privacy}",
                "received_events_url": "https://api.github.com/users/Pelican-Elegant/received_events",
                "type": "Organization",
                "site_admin": false
            },
            "html_url": "https://github.com/Pelican-Elegant/elegant",
            "description": "A responsive, minimal, and stylish theme for Pelican",
            "fork": false,
            "url": "https://api.github.com/repos/Pelican-Elegant/elegant",
            "forks_url": "https://api.github.com/repos/Pelican-Elegant/elegant/forks",
            "keys_url": "https://api.github.com/repos/Pelican-Elegant/elegant/keys{/key_id}",
            "collaborators_url": "https://api.github.com/repos/Pelican-Elegant/elegant/collaborators{/collaborator}",
            "teams_url": "https://api.github.com/repos/Pelican-Elegant/elegant/teams",
            "hooks_url": "https://api.github.com/repos/Pelican-Elegant/elegant/hooks",
            "issue_events_url": "https://api.github.com/repos/Pelican-Elegant/elegant/issues/events{/number}",
            "events_url": "https://api.github.com/repos/Pelican-Elegant/elegant/events",
            "assignees_url": "https://api.github.com/repos/Pelican-Elegant/elegant/assignees{/user}",
            "branches_url": "https://api.github.com/repos/Pelican-Elegant/elegant/branches{/branch}",
            "tags_url": "https://api.github.com/repos/Pelican-Elegant/elegant/tags",
            "blobs_url": "https://api.github.com/repos/Pelican-Elegant/elegant/git/blobs{/sha}",
            "git_tags_url": "https://api.github.com/repos/Pelican-Elegant/elegant/git/tags{/sha}",
            "git_refs_url": "https://api.github.com/repos/Pelican-Elegant/elegant/git/refs{/sha}",
            "trees_url": "https://api.github.com/repos/Pelican-Elegant/elegant/git/trees{/sha}",
            "statuses_url": "https://api.github.com/repos/Pelican-Elegant/elegant/statuses/{sha}",
            "languages_url": "https://api.github.com/repos/Pelican-Elegant/elegant/languages",
            "stargazers_url": "https://api.github.com/repos/Pelican-Elegant/elegant/stargazers",
            "contributors_url": "https://api.github.com/repos/Pelican-Elegant/elegant/contributors",
            "subscribers_url": "https://api.github.com/repos/Pelican-Elegant/elegant/subscribers",
            "subscription_url": "https://api.github.com/repos/Pelican-Elegant/elegant/subscription",
            "commits_url": "https://api.github.com/repos/Pelican-Elegant/elegant/commits{/sha}",
            "git_commits_url": "https://api.github.com/repos/Pelican-Elegant/elegant/git/commits{/sha}",
            "comments_url": "https://api.github.com/repos/Pelican-Elegant/elegant/comments{/number}",
            "issue_comment_url": "https://api.github.com/repos/Pelican-Elegant/elegant/issues/comments{/number}",
            "contents_url": "https://api.github.com/repos/Pelican-Elegant/elegant/contents/{+path}",
            "compare_url": "https://api.github.com/repos/Pelican-Elegant/elegant/compare/{base}...{head}",
            "merges_url": "https://api.github.com/repos/Pelican-Elegant/elegant/merges",
            "archive_url": "https://api.github.com/repos/Pelican-Elegant/elegant/{archive_format}{/ref}",
            "downloads_url": "https://api.github.com/repos/Pelican-Elegant/elegant/downloads",
            "issues_url": "https://api.github.com/repos/Pelican-Elegant/elegant/issues{/number}",
            "pulls_url": "https://api.github.com/repos/Pelican-Elegant/elegant/pulls{/number}",
            "milestones_url": "https://api.github.com/repos/Pelican-Elegant/elegant/milestones{/number}",
            "notifications_url": "https://api.github.com/repos/Pelican-Elegant/elegant/notifications{?since,all,participating}",
            "labels_url": "https://api.github.com/repos/Pelican-Elegant/elegant/labels{/name}",
            "releases_url": "https://api.github.com/repos/Pelican-Elegant/elegant/releases{/id}",
            "deployments_url": "https://api.github.com/repos/Pelican-Elegant/elegant/deployments"
        },
        "url": "https://api.github.com/notifications/threads/435117107",
        "subscription_url": "https://api.github.com/notifications/threads/435117107/subscription"
    }
]

I save the response to ghub-response variable. then the error comes up

ELISP> (nth 1 ghub-notif)
*** Eval error ***  Wrong type argument: listp, [((id . "435117107") (unread . t) (reason .......
ELISP> (assoc 'repository ghub-notif)
*** Eval error ***  Wrong type argument: listp, [((id . "435117107") ....

Why request can't parse the json response to equivalent elisp data structure correctly ? I think maybe the response contains [] square brackets.

Thanks for request.

azzamsa commented 5 years ago

Working with API response that din't have have square brackets is a breeze. It's the elisp equivalent generated by request.el for wayback API.

  ((url . "https://c3lt.de/35c3/talk/BRKHHG/")
   (archived_snapshots))
{
   "url": "https://c3lt.de/35c3/talk/BRKHHG/",
    "archived_snapshots": {}
}
  ((url . https://www\.nytimes\.com/2019/02/10/opinion/dan-savage-jeff-bezos-national-enquirer\.html)
   (archived_snapshots
    (closest
     (status . 200)
     (available . t)
     (url . http://web\.archive\.org/web/20190211001619/https://www\.nytimes\.com/2019/02/10/opinion/dan-savage-jeff-bezos-national-enquirer\.html)
     (timestamp . 20190211001619))))
{
    "url": "https://www.nytimes.com/2019/02/10/opinion/dan-savage-jeff-bezos-national-enquirer.html",
    "archived_snapshots": {
        "closest": {
            "status": "200",
            "available": true,
            "url": "http://web.archive.org/web/20190211073027/https://www.nytimes.com/2019/02/10/opinion/dan-savage-jeff-bezos-national-enquirer.html",
            "timestamp": "20190211073027"
        }
    }
}

Anyone had idea how to work with response that wrapped with [] square brackets ?

azzamsa commented 5 years ago

Turn out if JSON response inside [] (an array of object in Javascript), json-read-file will parse it as vector. I have hard time solving this, before I've an idea to see it's type. Now since it's a vector I can get the value using elt.

ELISP> (setq ghub-response (json-read-file "github.json"))
[((id . "44445566")
  (unread . t)
  (reason . "mention")
  (updated_at . "2019-02-11T10:41:23Z")
  (last_read_at . "2019-02-10T16:27:56Z")....

ELISP> (type-of ghub-response)
vector   <----- it was vector

ELISP> (nth 0 ghub-response)
*** Eval error ***  Wrong type argument: listp, [((id . "435345677")
(unread . t)... <----- failed to use list operation

ELISP> (elt ghub-response 0)
((id . "43511")
 (unread . t)
 (reason . "mention")
 (updated_at . "2019-02-11T10:41:23Z")
 (last_read_at . "2019-02-10T16:27:56Z") <----- works using vector operation