0

I try to make an API for my next website and I have trouble to get multiple query results with the same url in an express app.

Dummy data:

var data = [{
    articles : [{
        id : '0',
        url : 'foo',
        title : 'Foo',
        body : 'some foo bar',
        category : 'foo',
        tags : [
            'foo'
        ]
    }, {
        id : '1',
        url : 'foo-bar',
        title : 'Foo bar',
        body : 'more foo bar',
        category : 'foo',
        tags : [
            'foo', 'bar'
        ]
    }, {
        id : '2',
        url : 'foo-bar-baz',
        title : 'Foo bar baz',
        body : 'more foo bar baz',
        category : 'foo',
        tags : [
            'foo',
            'bar',
            'baz'
        ]
    }]
}, {
    users : [{
        name: 'Admin'
    }, {
        name: 'User'
    }]
}];

Router:

// Grabs articles by categories and tags
// http://127.0.0.1:3000/api/articles/category/foo/tag/bar
router.get('/articles/category/:cat/tag/:tag', function(req, res) {
  var articles = data[0].articles;
  var q = articles.filter(function (article) {
    return article.category === req.params.cat;
    return article.tags.some(function(tagId) { return tagId === req.params.tag;});
  });
  res.json(q);
});

How I can nest the results if I requesting the http://127.0.0.1:3000/api/articles/category/foo/tag/bar url? Now if I do this, tag url is ignored, only category requests have effect.

Thank You for your help!

2 Answers 2

1

You need to rewrite your return statement as follows:

return article.category === req.params.cat &&
       article.tags.some(function(tagId) {
           return tagId === req.params.tag;
       });

... using the && operator, otherwise you will only test on the first condition, never reaching the other statement.

Here is a test when request is on category 'foo' and tag 'bar':

var data =
[
  { articles:
    [
      { id: '0', url: 'audrey-hepburn', title: 'Audrey Hepburn', body: 'Nothing is impossible, the word itself says \'I\'m possible\'!', category: 'foo', tags: [ 'foo' ] },
      { id: '1', url: 'walt-disney', title: 'Walt Disney', body: 'You may not realize it when it happens, but a kick in the teeth may be the best thing in the world for you.', category: 'foo', tags: [ 'foo', 'bar' ] },
      { id: '2', url: 'unknown', title: 'Unknown', body: 'Even the greatest was once a beginner. Don\'t be afraid to take that first step.', category: 'bar', tags: [ 'foo', 'bar', 'baz' ] },
      { id: '3', url: 'neale-donald-walsch', title: 'Neale Donald Walsch', body: 'You are afraid to die, and you\'re afraid to live. What a way to exist.', category: 'bar', tags: [ 'foo', 'bar', 'baz' ] }
    ]
  },
  { users:
    [
      { name: 'Admin' },
      { name: 'User' }
    ]
  }
];

req = {params: {cat: 'foo', tag: 'bar'}};

var articles = data[0].articles;
var q = articles.filter(function (article) {
    return article.category === req.params.cat &&
           article.tags.some(function(tagId) { 
               return tagId === req.params.tag;
           });
});

document.write('<pre>', JSON.stringify(q, null, 4), '</pre>');

See how it matches the last entry.

Sign up to request clarification or add additional context in comments.

14 Comments

I think I might have misunderstood. You want to do requests like this: /articles/category/foo/tag/bar. Is that right? Could you put back the original router.get(/articles/category/:cat/tag/:tag', ... URL pattern and in the function just output res.json(req.params);. I want to make sure you see bot the category and tag in that params.
OK, that means the URL pattern is working correctly. Forget everything I wrote about that, I reverted my answer back to what it was before. Let me check now what else could be going wrong...
I updated my answer, using the data you have on github, and replaced the || operator with && which makes it required that both the cat and tag conditions are met.
I beautified a little bit the api router. Thank You again your help! :) github.com/DJviolin/horgalleryNode/blob/master/routes/api.js
No, I meant that as you moved the article.category === req.params.cat inside the some callback function, you actually multiply the execution of that test, which will always be the same. But really, this should not have much of a performance impact. It's OK.
|
1

Problem is here >>

return article.category === req.params.cat;
return article.tags.some(function(tagId) { return tagId === req.params.tag;});

first return statement will stop further action within function so you need if ... else or case or helper function here

3 Comments

return article.category === req.params.cat, article.tags.some(function(tagId) { return tagId === req.params.tag;}); seems like work. Is it a good solution? EDIT: Nope. Returning every category. Tags working instead.
No, return in this case will execute all but return last statement
You can try [articles].indexOf(el) and [tags].indexOf(el) if the both are Arrays.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.