Created
May 11, 2021 08:37
-
-
Save kagaim/1104849153258d37157b372eb913fd01 to your computer and use it in GitHub Desktop.
Using Shopify Storefront API to fetch recent posts, blog names and implement load more posts functionality
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Recent Posts | |
const container = document.querySelector('#blog-posts'); | |
const load_more = document.querySelector('#load-more'); | |
const spinner = document.querySelector("#spinner"); | |
const cat_list = document.querySelector('#sidebar-cat-list'); | |
const rp_title = document.querySelector('#sidebar-recent-posts'); | |
function showSpinner() { | |
spinner.style.display = 'block'; | |
} | |
function hideSpinner() { | |
spinner.style.display = 'none'; | |
} | |
function showLoadMore() { | |
load_more.style.display = 'inline-block'; | |
} | |
function hideLoadMore() { | |
load_more.style.display = 'none'; | |
} | |
// API Call | |
function apiCall(query, variables) { | |
return fetch('https://[shopify store name].myshopify.com/api/2021-04/graphql.json', { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json', | |
"Access-Control-Origin": "*", | |
'X-Shopify-Storefront-Access-Token': "[Hashed Password]" | |
}, | |
"body": JSON.stringify({ | |
query, | |
variables | |
}) | |
}).then(response => response.json()); | |
} | |
// Parse Returned Posts | |
function appendToDiv(div, new_html) { | |
// Put the new HTML into a temp div | |
// This causes browser to parse it as elements. | |
var temp = document.createElement('div'); | |
temp.innerHTML = new_html; | |
// Then we can find and work with those elements. | |
// Use firstElementChild b/c of how DOM treats whitespace. | |
var class_name = temp.firstElementChild.className; | |
var items = temp.getElementsByClassName(class_name); | |
var len = items.length; | |
for(i=0; i < len; i++) { | |
div.appendChild(items[0]); | |
} | |
} | |
// Parse Returned List Items | |
function appendToLI(li, new_html) { | |
// Put the new HTML into a temp div | |
// This causes browser to parse it as elements. | |
var temp = document.createElement('li'); | |
temp.innerHTML = new_html; | |
// Then we can find and work with those elements. | |
// Use firstElementChild b/c of how DOM treats whitespace. | |
var class_name = temp.firstElementChild.className; | |
var items = temp.getElementsByClassName(class_name); | |
var len = items.length; | |
for(i=0; i < len; i++) { | |
li.appendChild(items[0]); | |
} | |
} | |
hideLoadMore(); | |
showSpinner(); | |
// Recent Posts Query | |
const recentPostsQuery = `{ | |
articles(first: 4, reverse: true) { | |
edges { | |
node { | |
title | |
url | |
publishedAt | |
image(crop: CENTER, maxHeight: 600, maxWidth: 600) { | |
src | |
} | |
blog { | |
title | |
} | |
} | |
cursor | |
} | |
pageInfo { | |
hasNextPage | |
} | |
} | |
blogs(first: 20, sortKey: TITLE) { | |
edges { | |
node { | |
title | |
url | |
} | |
} | |
} | |
}`; | |
// Load More Posts Query | |
const loadMorePostsQuery = `query loadMorePosts($after: String) { | |
articles(first: 4, reverse: true, after: $after) { | |
edges { | |
node { | |
title | |
url | |
publishedAt | |
image(crop: CENTER, maxHeight: 600, maxWidth: 600) { | |
src | |
} | |
blog { | |
title | |
} | |
} | |
cursor | |
} | |
pageInfo { | |
hasNextPage | |
} | |
} | |
blogs(first: 20, sortKey: TITLE) { | |
edges { | |
node { | |
title | |
url | |
} | |
} | |
} | |
}`; | |
// Send Query via API | |
apiCall(recentPostsQuery).then(response => { | |
// Categories | |
let categories = response.data.blogs.edges; | |
categories.forEach(blogCategories); | |
// Recent Posts | |
let next_page = response.data.articles; | |
let has_next_page = next_page.pageInfo.hasNextPage; | |
if(has_next_page) { | |
load_more.setAttribute('data-cursor', next_page.edges[3].cursor); | |
} | |
let posts = response.data.articles.edges; | |
posts.forEach(recentPosts); | |
hideSpinner(); | |
showLoadMore(); | |
}); | |
// Categories Function | |
function blogCategories(cat) { | |
let list = ` | |
<li class="sb__cat-item"><a class="sb__cat-link" href="${cat.node.url}">${cat.node.title}</a></li> | |
`; | |
appendToLI(cat_list,list); | |
} | |
// Recent Posts Function | |
function recentPosts(article, div, new_html) { | |
let mydate = new Date(article.node.publishedAt); | |
let month = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"][mydate.getMonth()]; | |
let day = mydate.getDate(); | |
let date = month + ' ' + day + ', ' + mydate.getFullYear(); | |
let post = ` | |
<article class="rp-col"> | |
<a href="${article.node.url}" class="card" aria-label="${article.node.title}"> | |
<img class="lazyloaded" src="${article.node.image.src}" alt="${article.node.title}"> | |
<div class="card-body"> | |
<h3>${article.node.title}</h3> | |
<p>${date}</p> | |
<p>${article.node.blog.title}</p> | |
</div> | |
</a> | |
</article> | |
`; | |
let title = ` | |
<li class="rp__title-item"><a class="rp__title-link" href="${article.node.url}">${article.node.title}</a></li> | |
`; | |
// append results to end of blog posts | |
appendToDiv(container, post); | |
// append recent post titles to sidebar | |
appendToLI(rp_title,title); | |
} | |
// Load More Button Click Event | |
load_more.addEventListener('click', () => { | |
hideLoadMore(); | |
showSpinner(); | |
let cursor = load_more.getAttribute('data-cursor'); | |
let variables = { | |
"after": cursor | |
} | |
apiCall(loadMorePostsQuery,variables).then(response => { | |
let next_page = response.data.articles; | |
let has_next_page = next_page.pageInfo.hasNextPage; | |
if(has_next_page) { | |
load_more.setAttribute('data-cursor', next_page.edges[3].cursor); | |
} else { | |
load_more.innerHTML = "No more posts" | |
load_more.disabled = true; | |
} | |
let posts = response.data.articles.edges; | |
posts.forEach(recentPosts); | |
hideSpinner(); | |
showLoadMore(); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment