From 21fa7a83df2d5bca85d1db87fbd71f1ee707533c Mon Sep 17 00:00:00 2001 From: yarphen Date: Sun, 17 May 2020 03:27:05 +0300 Subject: [PATCH] Async tweets --- src/_tables/TableViewPage.vue | 7 ++-- src/lib/tweet.js | 69 +++++++++++++++++++++++++++++------ 2 files changed, 61 insertions(+), 15 deletions(-) diff --git a/src/_tables/TableViewPage.vue b/src/_tables/TableViewPage.vue index d6fef0f..0df16b4 100644 --- a/src/_tables/TableViewPage.vue +++ b/src/_tables/TableViewPage.vue @@ -94,7 +94,7 @@ import _sortBy from 'lodash/sortBy'; import { mapGetters } from 'vuex'; import tableResize from '@/lib/table-resize'; import sheetclip from '@/lib/sheetclip'; -import { fetchTweetCounts } from '@/lib/tweet'; +import { fetchTweetCounts, initialPatch } from '@/lib/tweet'; import { isLink, parseNumber } from '@/utils/str'; @@ -289,11 +289,12 @@ export default { return this.$http.get(apiUrl) .then(result => { this.$store.dispatch('pageLoader', false); - this.sheet = result; + this.sheet = initialPatch(result); setTimeout(() => this.initResize(), 400); }) - .then(() => fetchTweetCounts(this.parsedDataSet)) + .then(() => fetchTweetCounts(this.sheet)) + .then(result => { this.sheet = result }) .catch(err => { console.warn('failed to fetch sheet:', err); diff --git a/src/lib/tweet.js b/src/lib/tweet.js index db5ff56..262206d 100644 --- a/src/lib/tweet.js +++ b/src/lib/tweet.js @@ -4,9 +4,14 @@ const DOI_BASE_URL = 'https://doi.org/'; const BASE_API_URL = 'https://api.altmetric.com/v1/doi/'; +const TWEET_CELL_INDEX = 1; + const getDoiIds = (dataSet) => { - return dataSet.map((row) => { - const firstLinkToDoi = (row || []).find(item => item.startsWith(DOI_BASE_URL)); + return dataSet.rows.map((row) => { + const firstLinkToDoi = ((row && row.cells) || []) + .map(item => item && item.v) + .filter(value => !!value) + .find(value => value.startsWith(DOI_BASE_URL)); if (!firstLinkToDoi) { return null; } @@ -24,23 +29,63 @@ const processTweetCounts = (tweetCounts, doiIds) => { return tweetCountsByIndex; }; -const patchWithTweetsNumbers = (result, tweetCountsByIndex) => { - return result.map((row, index) => ([ - row[0], - index === 0 ? '# of Tweets' : (tweetCountsByIndex[index] || '-'), - ...row.slice(1) - ])); +export const initialPatch = ({ rows, header, ...rest }) => { + const newHeader = [...(header || [])]; + newHeader.splice(TWEET_CELL_INDEX, 0, '# of Tweets'); + const newRows = rows.map((row) => { + const { cells } = row || {}; + const newCells = [...(cells || [])]; + newCells.splice(TWEET_CELL_INDEX, 0, { + id: `${Math.random()}`.slice(2), + v: '...', + t: 'string', + }); + return { + ...row, + cells: newCells, + }; + }); + return { + ...rest, + rows: newRows, + header: newHeader, + }; +}; + +const finalPatch = ({ rows, ...rest }, tweetCountsByIndex) => { + const newRows = rows.map((row, rowIndex) => { + const { cells } = row || {}; + const newCells = [...(cells || [])].map((item, index) => ( + TWEET_CELL_INDEX === index ? ({ + v: tweetCountsByIndex[rowIndex] || 'Error: no ID found', + type: 'string', + id: `${Math.random()}`.slice(2), + }) : item + )); + return { + ...row, + cells: newCells, + }; + }); + return { + ...rest, + rows: newRows, + }; }; -export const fetchTweetCounts = async (dataSet) => { - const doiIds = getDoiIds(dataSet); + +export const fetchTweetCounts = async (sheet) => { + const doiIds = getDoiIds(sheet); const doiIdsUnique = [...new Set(doiIds.filter(id => !!id))]; + const tweetCounts = await Promise.all(doiIdsUnique.map( id => fetch(`${BASE_API_URL}${id}`) .then(res => res.json()) .then(res => ({ count: `${_get(res, 'cited_by_tweeters_count', '-')}`, id })) + .catch(() => ({ count: 'Error fetching data', id })), )); + const tweetCountsByIndex = processTweetCounts(tweetCounts, doiIds); - const newDataSet = patchWithTweetsNumbers(dataSet, tweetCountsByIndex); - return newDataSet; + + return finalPatch(sheet, tweetCountsByIndex); };