【问题标题】:Remove JSON Objects With Date Already Passed删除日期已过的 JSON 对象
【发布时间】:2019-02-12 19:58:56
【问题描述】:

我正在尝试按名为“事件日期”的元字段对 Shopify 博客文章进行排序。我调用了我的articles.JSON,但它没有附带metafields.JSON,所以我必须获取该数组并通过foreach 函数将它附加到每篇文章的元字段。

这是每篇文章的 metafields.json 的设置方式:

{  
   "metafields":[  
      {  
         "id":5994805788772,
         "namespace":"global",
         "key":"Event-Date",
         "value":"1549256400",
         "value_type":"string",
         "description":null,
         "owner_id":15977611364,
         "created_at":"2019-02-06T18:31:44-05:00",
         "updated_at":"2019-02-06T18:31:44-05:00",
         "owner_resource":"article"
      },
      {  
         "id":5994805821540,
         "namespace":"global",
         "key":"Event-Time",
         "value":"6:00pm - 8:00pm",
         "value_type":"string",
         "description":null,
         "owner_id":15977611364,
         "created_at":"2019-02-06T18:31:45-05:00",
         "updated_at":"2019-02-06T18:31:45-05:00",
         "owner_resource":"article"
      },
      {  
         "id":6010564542564,
         "namespace":"global",
         "key":"Location",
         "value":"18th Street Location",
         "value_type":"string",
         "description":null,
         "owner_id":15977611364,
         "created_at":"2019-02-07T13:16:05-05:00",
         "updated_at":"2019-02-07T14:05:08-05:00",
         "owner_resource":"article"
      }
   ]
}

我如何在下面附加 metafields.JSON:

var request = new XMLHttpRequest();

request.open('GET', '/admin/blogs/43130421348/articles.json');
request.responseType = 'json';
request.send();

request.onload = function() {
    var articleList = request.response; 
    var articleArray = articleList.articles;
    var date = new Date();
    var ticks = Math.floor(date.getTime() / 1000);
    var count = 0;
    articleArray.forEach(function(entry,index, object){
    var metaRequest = new XMLHttpRequest();
    metaRequest.open('GET', '/admin/blogs/43130421348/articles/'+ entry.id + '/metafields.json');
    metaRequest.responseType = 'json';
    metaRequest.send();
    console.log(index);

    metaRequest.onload = function() {
        var articleMetaObj = metaRequest.response;
        var articleMetaArr = articleMetaObj.metafields;
        entry.metafields = articleMetaArr; 
        var eventDate = entry.metafields[0].value;
   }

 });

};

我现在正试图删除与当前日期相比已经过了日期(“Key”:“Event-Date”)的任何文章。我查看了以下Stack Overflow Post 在 foreach 循环中删除对象的内容,但没有一个解决方案证明实际上可以删除所有文章。它偶尔会摆脱所有这些,但有时会留在其中一个物体中。

我也尝试了一个数组过滤器,但是当我使用它时,我得到的只是一个空数组。我现在已经坚持了一段时间,因此非常感谢任何有关解决它的帮助。

【问题讨论】:

    标签: javascript json shopify shopify-template


    【解决方案1】:

    我认为,如果您等到附加所有元数据,然后在全部完成后,使用articleArray.filter 取出您不想要的元数据,这将是最简单的。为此,您有两种选择:

    选项 1 - 旧方法 (setInterval)

    在这里,我们在检索元数据时保持计数,并创建一个间隔来检查它们何时全部完成。完成后,将调用(完成)一个允许继续处理的函数。

    var request = new XMLHttpRequest();
    
    request.open('GET', '/admin/blogs/43130421348/articles.json');
    request.responseType = 'json';
    request.send();
    
    request.onload = function () {
        var articleList = request.response;
        var articleArray = articleList.articles;
        var date = new Date();
        var ticks = Math.floor(date.getTime() / 1000);
        var count = 0;  //to keep track of how many metafields have been retrieved
        var checkInterval = null;
    
        articleArray.forEach(function (entry, index) {
            var metaRequest = new XMLHttpRequest();
            metaRequest.open('GET', '/admin/blogs/43130421348/articles/' + entry.id + '/metafields.json');
            metaRequest.responseType = 'json';
            metaRequest.send();
            console.log(index);
    
            metaRequest.onload = function () {
                var articleMetaObj = metaRequest.response;
                var articleMetaArr = articleMetaObj.metafields;
                entry.metafields = articleMetaArr;
                count++;
            };
        });
    
        //Function to continue processing
        var finish = function () {
            articleArray = articleArray.filter(a => new Date(a.metafields[0].value).getTime() < date.getTime());
            //Continue on...
        };
    
        //Wait until all metafields are retrieved to continue
        checkInterval = setInterval(function () {
            if (count === articleArray.length - 1) {
                clearInterval(checkInterval);
                finish();
            }
        }, 500);
    };
    

    选项 2 - 新的 Razmatazz(承诺和异步/等待)

    Promisesasync/await 允许在处理异步操作时编写一些更好看的代码。

    如果您想使用这些,我建议您深入研究文档以更加熟悉,但这是您的任务可能的样子。

    //Functions that return Promises can be awaited...
    var get = url => new Promise((resolve, reject) => {
        var request = new XMLHttpRequest();
        request.open('GET', url);
        request.responseType = 'json';
        //resolve is called when successful
        request.onload = () => resolve(request.response);
        //reject is called when there's a problem
        request.onerror = err => reject(err);
        request.send();
    });
    
    //await keyword must appear in an async function
    var getArticles = async () => {
        var articleList = await get('/admin/blogs/43130421348/articles.json');
        return articleList.articles;
    };
    
    //Promise.all takes an array of promises and resolves when all of them are finished
    //This lets you skip the messy setInterval stuff
    var getArticleMetafields = async articles => {
        var requests = [];
        articles.forEach(a => {
            var url = '/admin/blogs/43130421348/articles/' + a.id + '/metafields.json';
            var promise = get(url);
            requests.push(promise);
        });
        var responses = await Promise.all(requests);
        responses.forEach((response, i) => {
            articles[i].metafields = response.metafields;
        });
        return articles;
    };
    
    //Notice the async on the handler
    document.addEventListener('DOMContentLoaded', async () => {
        var articles = await getArticles();
        articles = await getArticleMetafields(articles);
        var date = new Date();
        articles = articles.filter(a => new Date(a.metafields[0].value) < date);
        //Continue...
    });
    

    希望这会有所帮助。干杯!

    【讨论】:

    • 等到我附加了所有东西之后,我还必须弄清楚如何在其范围之外使用 json 对象?我也一直在尝试解决这个问题,但也没有太多运气。
    • @KC-da 是的,需要重新安排;这就是为什么我也建议使用filteredArticles 方法。这对你不起作用吗?如果没有,我可以向您展示如何重新安排它的示例。
    • 问题在于将元字段添加到我的数组的 foreach 循环变得很麻烦,因为现在它要多次运行所有内容。过滤文章后,我还希望能够通过它们的日期对剩余的文章进行排序(从最近到最远)是否有任何方法可以在完成后超出范围以打破 foreach 循环?
    • @KC-da 是的,明天我会尽力为你做一个例子
    • 嘿,我的 b,直到现在才知道。但这确实很有希望并且很有帮助。非常感谢!
    【解决方案2】:

    您的条目是文章吗?然后你可以忽略使用:

    request.onload = function() {
    var articleList = request.response; 
    var articleArray = articleList.articles;
    var date = new Date();
    var ticks = Math.floor(date.getTime() / 1000);
    var count = 0;
    articleArray.forEach(function(entry,index, object){
       if(entry.'Key' !== 'Event-Date'){
            var metaRequest = new XMLHttpRequest();
            metaRequest.open('GET', '/admin/blogs/43130421348/articles/'+ entry.id + '/metafields.json');
            metaRequest.responseType = 'json';
            metaRequest.send();
            console.log(index);
    
            metaRequest.onload = function() {
            var articleMetaObj = metaRequest.response;
            var articleMetaArr = articleMetaObj.metafields;
            entry.metafields = articleMetaArr; 
            var eventDate = entry.metafields[0].value;
           }
       }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-04
      • 2012-06-17
      • 2012-07-23
      • 2012-01-20
      • 1970-01-01
      • 1970-01-01
      • 2011-03-21
      • 2022-06-14
      相关资源
      最近更新 更多