Search code examples
javascriptnode.jsreactjstwitternext.js

How to filter and array of tweets by a hastag?


I have an array of tweet objects that I list on a page. I display all the hashtags from all the tweets in a separate HTML element. When a user clicks on a hashtag, I'd like it to filter my array of tweets to only display tweets with the clicked hashtag.

Here is one of the tweet objects in the array:

{
  "created_at": "Mon Dec 06 14:13:27 +0000 2021",
  "id": 1467859736775344000,
  "id_str": "1467859736775344128",
  "text": "JUST IN – Professional soccer player receives world’s first #Bitcoin Lightning payroll payment 🙌 https://...",
  "truncated": false,
  "entities": {
    "hashtags": [
      {
        "text": "Bitcoin",
        "indices": [
          60,
          68
        ]
      }
    ],
    "symbols": [],
    "user_mentions": [],
    "urls": [],
    "media": [
      {
        "id": 1467859588900925400,
        "id_str": "1467859588900925448",
        "indices": [
          97,
          120
        ],
        "media_url": "http://pbs.twimg.com/media/FF7ihOCXMAgPCed.jpg",
        "media_url_https": "https://pbs.twimg.com/media/FF7ihOCXMAgPCed.jpg",
        "url": "https://...",
        "display_url": "pic.twitter.com/CYScG5iUm9",
        "expanded_url": "https://twitter.com/BitcoinMagazine/status/1467859736775344128/photo/1",
        "type": "photo",
        "sizes": {
          "small": {
            "w": 680,
            "h": 481,
            "resize": "fit"
          },
          "thumb": {
            "w": 150,
            "h": 150,
            "resize": "crop"
          },
          "large": {
            "w": 1966,
            "h": 1390,
            "resize": "fit"
          },
          "medium": {
            "w": 1200,
            "h": 848,
            "resize": "fit"
          }
        }
      }
    ]
  },
  "extended_entities": {
    "media": [
      {
        "id": 1467859588900925400,
        "id_str": "1467859588900925448",
        "indices": [
          97,
          120
        ],
        "media_url": "http://pbs.twimg.com/media/FF7ihOCXMAgPCed.jpg",
        "media_url_https": "https://pbs.twimg.com/media/FF7ihOCXMAgPCed.jpg",
        "url": "https://...",
        "display_url": "pic.twitter.com/CYScG5iUm9",
        "expanded_url": "https://twitter.com/BitcoinMagazine/status/1467859736775344128/photo/1",
        "type": "photo",
        "sizes": {
          "small": {
            "w": 680,
            "h": 481,
            "resize": "fit"
          },
          "thumb": {
            "w": 150,
            "h": 150,
            "resize": "crop"
          },
          "large": {
            "w": 1966,
            "h": 1390,
            "resize": "fit"
          },
          "medium": {
            "w": 1200,
            "h": 848,
            "resize": "fit"
          }
        }
      }
    ]
  },
  "metadata": {
    "result_type": "popular",
    "iso_language_code": "en"
  },
  "source": "<a href=\"https://mobile.twitter.com\" rel=\"nofollow\">Twitter Web App</a>",
  "in_reply_to_status_id": null,
  "in_reply_to_status_id_str": null,
  "in_reply_to_user_id": null,
  "in_reply_to_user_id_str": null,
  "in_reply_to_screen_name": null,
  "user": {
    "id": 361289499,
    "id_str": "361289499",
    "name": "Bitcoin Magazine",
    "screen_name": "BitcoinMagazine",
    "location": "Nashville, TN",
    "description": "The Most Trusted Voice In #Bitcoin• Conference 🎟 https://... \n• Watch 🎥 https://...• Learn ⚡️https://...",
    "url": "https://...",
    "entities": {
      "url": {
        "urls": [
          {
            "url": "https://...",
            "expanded_url": "http://BitcoinMagazine.com",
            "display_url": "BitcoinMagazine.com",
            "indices": [
              0,
              23
            ]
          }
        ]
      },
      "description": {
        "urls": [
          {
            "url": "https://...",
            "expanded_url": "http://b.tc/conference",
            "display_url": "b.tc/conference",
            "indices": [
              49,
              72
            ]
          },
          {
            "url": "https://...",
            "expanded_url": "http://b.tc/youtube",
            "display_url": "b.tc/youtube",
            "indices": [
              84,
              107
            ]
          },
          {
            "url": "https://...",
            "expanded_url": "http://b.tc/21days",
            "display_url": "b.tc/21days",
            "indices": [
              118,
              141
            ]
          }
        ]
      }
    },
    "protected": false,
    "followers_count": 1737059,
    "friends_count": 635,
    "listed_count": 11533,
    "created_at": "Wed Aug 24 15:14:54 +0000 2011",
    "favourites_count": 20000,
    "utc_offset": null,
    "time_zone": null,
    "geo_enabled": true,
    "verified": true,
    "statuses_count": 19049,
    "lang": null,
    "contributors_enabled": false,
    "is_translator": false,
    "is_translation_enabled": false,
    "profile_background_color": "000000",
    "profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png",
    "profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png",
    "profile_background_tile": false,
    "profile_image_url": "http://pbs.twimg.com/profile_images/1444022922377576453/AzvXYXGr_normal.jpg",
    "profile_image_url_https": "https://pbs.twimg.com/profile_images/1444022922377576453/AzvXYXGr_normal.jpg",
    "profile_banner_url": "https://pbs.twimg.com/profile_banners/361289499/1628624645",
    "profile_link_color": "FFA207",
    "profile_sidebar_border_color": "000000",
    "profile_sidebar_fill_color": "000000",
    "profile_text_color": "000000",
    "profile_use_background_image": false,
    "has_extended_profile": false,
    "default_profile": false,
    "default_profile_image": false,
    "following": null,
    "follow_request_sent": null,
    "notifications": null,
    "translator_type": "regular",
    "withheld_in_countries": []
  },
  "geo": null,
  "coordinates": null,
  "place": null,
  "contributors": null,
  "is_quote_status": false,
  "retweet_count": 386,
  "favorite_count": 2612,
  "favorited": false,
  "retweeted": false,
  "possibly_sensitive": false,
  "lang": "en"
}

The hashtags are stored in an array, with a text field. However, I cannot figure out how to filter by the text field within the hashtag.

Here's my function that takes in an array of tweets, however it's currently only returning an array of filtered hashtags and not the tweets themselves:

  const filterTweetsByHashtag = (hashtag: string) => {
    setOriginalTweets(tweets);
    const filteredTweets = tweets.filter((tweet: any) => {
      const hashtags = tweet.entities.hashtags;
      return hashtags.some((hashtag: any) => hashtag.text === hashtag);
    });
    setTweets(filteredTweets);
  };

I'm not sure where I'm going wrong, I can filter strings and numbers fine, but when it comes to filtering an array within an array I'm quite lost. Any additional insight would be appreciated!


Solution

  • You don't get the result it's because your variable name:

    You can look at this code below:

    return hashtags.some((hashtag: any) => hashtag.text === hashtag);
    

    From that code above, your hashtag.text is compare with hashtag from hashtags, not from hashtag you provide.

    Maybe you can try this:

    return hashtags.some((h: any) => h.text === hashtag);