功能
搜索Github用戶,並顯示個人訊息和最新的Repository。
學習到的知識點
JS
- Ajax 實作串接 Github API
- Jquery Ajax
簡介
Demo
HTML
結構
HTML內容不多,多為用JS動態產生的內容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <body> <nav class="navbar navbar-dark bg-primary mb-3"> <div class="container"> <a href="#" class="navbar-brand">GitHub Finder</a> </div> </nav> <div class="container searchContainer"> <div class="search card card-body"> <h1>Search GitHub Users</h1> <p class="lead">Enter a username to fetch a user profile and repos</p> <div id="error"></div> <input type="text" id="searchUser" class="form-control" placeholder="GitHub Username..." /> </div> <br /> <div id="profile"></div> </div> <footer class="mt-5 p-3 text-center bg-light">GitHub Finder ©</footer> <script src="script.js"></script> </body>
|
CSS
使用Bootswatch
JS
取得資料,過濾資料
data裡面放的資料為clent_id
,client_secret
,在還沒有放置時,一開始都可以正常存取,但後來會出現403拒絕存取的錯誤,在stackoverflow找到解答,需要有valid User-Agent header,所以要加上clent_id
,client_secret
。
success
為成功運行後執行的function,insertProfile()
函式利用物件的方法,將json檔取出,這邊先過濾一整包資料,因為會出現no data的狀況。相較之下,repository就不會出現沒有資料顯示null的狀況,所以只要這邊做資料過濾就可以。
jQuery.ajax(url [, settings])
參數 |
型別 |
說明 |
url |
String |
指定要進行呼叫的位址 |
data |
Object |
要傳給 server 的 Key/value 值對 |
success |
Function |
Ajax 請求完成時 (必需是 success) 呼叫的 callback |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| $(document).ready(function () { $("#searchUser").on("change", function (e) { let username = e.target.value; $.ajax({ url: "https://api.github.com/users/" + username, data: { client_id: "b9315bcd5a07fcd759d8", client_secret: "a2b698bf7e7c02f898197cf136d1a41f704ca8e4", }, success: function insertProfile(user) { let obj = {}; obj.avatar_url = user.avatar_url || "no data"; obj.profile_url = user.html_url || "no data"; obj.public_gists = user.public_gists || "no data"; obj.public_repos = user.public_repos || "no data"; obj.followers = user.followers || "no data"; obj.following = user.following || "no data"; obj.company = user.company || "no data"; obj.location = user.location || "no data"; obj.blog = user.blog || "no data"; console.log(obj); }, }); }); });
|
顯示出來的過濾內容
Profile放到DOM裡面
將取得的資料放到DOM裡面,使用.html(profile)
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| var profile = ` <div class="card card-body mb-3"> <div class="row"> <div class="col-md-3"> <img class="img-fluid mb-2" src="${obj.avatar_url}"> <a href="${user.html_url}" target="_blank" class="btn btn-primary btn-block mb-4">View Profile</a> </div> <div class="col-md-9"> <span class="badge badge-primary">Public Repos: ${obj.public_repos}</span> <span class="badge badge-secondary">Public Gists: ${obj.public_gists}</span> <span class="badge badge-success">Followers: ${obj.followers}</span> <span class="badge badge-info">Following: ${obj.following}</span> <br><br> <ul class="list-group"> <li class="list-group-item">Company: ${obj.company}</li> <li class="list-group-item">Website/Blog: ${obj.blog}</li> <li class="list-group-item">Location: ${obj.location}</li> <li class="list-group-item">Member Since: ${user.created_at}</li> </ul> </div> </div> </div> <h3 class="page-heading mb-3">Latest Repos</h3> <div id="repos"></div> `; $("#profile").html(profile); },
|
取得repo資料
- 一樣透過網址也可以先觀察到json格式的資料,所以透過url來取得api的資料。
data裡面的sort
為排序的意思,asc代表正序,desc代表倒序。per_page代表要取得五筆資料。
error為發現錯誤執行的function,jqXR為jQuery 1.5 版後,所有 jQuery 的 Ajax 方法 ($.get, $.post, $.ajax, …) 都會返回一個 jqXHR object。
404為jqXHR.status的一種狀態。
- 使用到
setTimeout()
為輸入的內容沒有該使用者時,出現2.3s的錯誤警告,再自動清空輸入內容,與profile還有repo,增加使用者體驗。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| $.ajax({ url: "https://api.github.com/users/" + username + "/repos", data: { client_id: "b9315bcd5a07fcd759d8", client_secret: "a2b698bf7e7c02f898197cf136d1a41f704ca8e4", sort: "created: asc", per_page: 5, }, error: function (jqXHR) { var msg = ""; if (jqXHR.status == 404) { msg = `<div class = "alert alert-danger"> Please enter again User does not exist</div>`; } $("#error").html(msg);
setTimeout(() => { $("#searchUser").val(""); $("#repos").html(""); $("#error").html(""); $("#profile").html(""); }, 2300); }, success: function insertRopo(repo_obj) { console.log(repo_obj); }, });
|
印出來得到的repo就會是我們要的前五筆最新資料。
Repo放到DOM裡
- 讀取連續五筆陣列資料,需要使用到
each
。這邊我遇到了一個錯誤,忘記了jquery語法,一直使用foreach
,導致資料一直無法讀取。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| $.each(repo_obj, function (index, repo) { $("#repos").append(` <div class="card card-body mb-2"> <div class="row"> <div class="col-md-6"> <a href="${repo.html_url}" target="_blank" class="font-weight-bold">${repo.name}</a> </div> <div class="col-md-6"> <span class="badge badge-primary">Stars: ${repo.stargazers_count}</span> <span class="badge badge-secondary">Watchers: ${repo.watchers_count}</span> <span class="badge badge-success">Forks: ${repo.forks_count}</span> </div> </div> </div> `); });
|
遇到的錯誤
錯誤一
一直以為repo的dom是要新增一個div
,在html才能夠放上去,所以直接在html加上了div
,然後使用.html()
更新repo的內容,發現只會出現一筆,所以換成了append
,就可以成功跑出五筆。
但出現五筆後,每當我換一位使用者的名字時,他就會一直疊加資料,從五筆變成十筆,十五筆,非常可怕。
解決這個問題花了非常多的時間,後來才發現,放repo的div
需要動態產生,動態產生時,就可以避免掉疊加的情況。
所以在profile的html裡,最後加上<div id="repos"></div>
,就可以解決問題。
錯誤二
keyup會不停的被觸發,輸入可能五個字時他就會被觸發二十幾次,導致repo的內容會顯示超過五筆,Error提醒也會不停被觸發,目前還在釐清這個問題。
但是,換成change之後,等待使用者輸入完成後,才觸發,就可以解決這個問題。
參考文章
jQuery Ajax