1

I am trying to show a Rss feed in Nuxt with Axios.

I can get:

  • title
  • link
  • description

It is working but for the images which are in:

<media:content url="https://uploads-ssl.webflow.com/60f1911b212fd90baa99ee92/00e5cfa7_mv2.jpg" medium="image >

I can't find the way to access it.

Here is my axios:

<script>
  asyncData ({params}, callback) {
    axios.get("https://yaniimodels.webflow.io/categories/rss.xml" )
      .then((res) => {
        var parseString = require('xml2js').parseString
        var xml = res.data
        parseString(xml, (message, xmlres) => {
          callback(null,{ data: xmlres.rss.channel[0].item})
        })
      })
      .catch((e) => {
        callback({ statusCode: 404, message: 'error' })
      })
  },
</script>

and in my template:

<template>
  <ul>
    <li v-for="item in data" :key="item.id">
      <a :href="item.link">
        {{item.title}}
        {{item.description}}
      </a>
    </li>
  </ul>
</template>

My rss.xml is like this :

<item>
    <title>Yanii Models | Ben and Ezra</title>
    <link>https://yaniimodels.webflow.io/categories/ben-and-ezra</link>
    <guid>https://yaniimodels.webflow.io/categories/ben-and-ezra</guid>
    <description>Petit Bâteau</description>
    <pubDate>Fri, 16 Jul 2021 16:27:00 GMT</pubDate>
    <media:content url="https://uploads-ssl.webflow.com/60f1911b212fd90baa99ee92/60f1b23cf09c3f73a4f92a1b_b79a66_8fa332a4dea94558b5f1e97200e5cfa7_mv2.jpg" medium="image"/>
    <media:thumbnail url="https://uploads-ssl.webflow.com/60f1911b212fd90baa99ee92/60f1b23cf09c3f73a4f92a1b_b79a66_8fa332a4dea94558b5f1e97200e5cfa7_mv2.jpg"/>
</item>
kissu
  • 40,416
  • 14
  • 65
  • 133
J.O
  • 117
  • 1
  • 12
  • The url `https://uploads-ssl.webflow.com/60f1911b212fd90baa99ee92/00e5cfa7_mv2.jpg` looks to be protected actually. – kissu Jul 20 '21 at 14:42
  • 1
    Hello Kissu sorry i cut it coz it was long one here is the full url : https://uploads-ssl.webflow.com/60f1911b212fd90baa99ee92/60f1b23cf09c3f73a4f92a1b_b79a66_8fa332a4dea94558b5f1e97200e5cfa7_mv2.jpg – J.O Jul 20 '21 at 14:45
  • So, what is your actual issue? You don't know how to parse it properly into something readable or how to display an image in Nuxt? – kissu Jul 20 '21 at 14:49
  • My actual issue is how to parse it properly for get the url of the image inside : – J.O Jul 20 '21 at 14:51
  • We could make this with regex but there is probably a simpler way. Do you have a JSON at some point? Never really worked with XML before. What is `parseString` giving you? – kissu Jul 20 '21 at 14:53
  • I dont have a JSON at some point i think Kissu i use 'xml2js' and i followed a tutorial for use it im kind of lost with RSS feed – J.O Jul 20 '21 at 14:59

2 Answers2

2

To display the RSS feed:

  1. @nuxtjs/axios is commonly used with Nuxt, which provides access to axios via the $axios context property (1st argument for asyncData). There's no need to import it in your component.

  2. The asyncData() callback parameter is deprecated. Use async/await instead.

  3. Use the Promise-based xml2js parser API for more succinct code.

  4. xml2js seems to wrap all propertries in an array, so you'll have to unwrap it (or index into it, which would be inconvenient to me).

  5. There is no item.id property, but there's item.guid. Use that for the v-for item key.

  6. The image URL is stored in media:content.$.url of each item. You could bind that URL to <img>.src.

<script>
export default {
  async asyncData ({ $axios 1️⃣, params }, /* callback 2️⃣ */) {
    const res = await $axios.get("https://yaniimodels.webflow.io/categories/rss.xml")
    const xmlres = await parseStringPromise(res.data) 3️⃣
    
    4️⃣
    const data = xmlres.rss.channel[0].item.map(item => {
      const newEntries = Object.entries(item).map(([key,val]) => [key, val[0]])
      return Object.fromEntries(newEntries)
    })

    return { data }
  }
}
</script>

<template>
  <ul>
    <li v-for="item in data" :key="item.guid"> 5️⃣
      ...
      <img :src="item['media:content'].$.url"> 6️⃣
    </li>
  </ul>
</template>

demo

tony19
  • 125,647
  • 18
  • 229
  • 307
1

I know that tony already got an accepted answer but here is my approach on this one, I thought it may still be relevant to share.

I used fast-xml-parser and achieved to have the following JSON from your xml with the ignoreAttributes: false option (because we needed your url attribute).

{
  "title": "Yanii Models | Ben and Ezra",
  "link": "https://yaniimodels.webflow.io/categories/ben-and-ezra",
  "guid": "https://yaniimodels.webflow.io/categories/ben-and-ezra",
  "description": "Petit Bâteau",
  "pubDate": "Fri, 16 Jul 2021 16:27:00 GMT",
  "media:content": {
    "@_url": "https://uploads-ssl.webflow.com/60f1911b212fd90baa99ee92/60f1b23cf09c3f73a4f92a1b_b79a66_8fa332a4dea94558b5f1e97200e5cfa7_mv2.jpg",
    "@_medium": "image"
  },
  "media:thumbnail": {
    "@_url": "https://uploads-ssl.webflow.com/60f1911b212fd90baa99ee92/60f1b23cf09c3f73a4f92a1b_b79a66_8fa332a4dea94558b5f1e97200e5cfa7_mv2.jpg"
  }
}

Here is the whole code to integrate a basic page

<template>
  <div>
    <h1>{{ jsonObj.title }}</h1>
    <p>{{ jsonObj.description }}</p>
    <a :href="jsonObj.link">Link</a>

    <br />
    <img :src="jsonObj['media:thumbnail']['@_url']" alt="thumbnail image" />
    <br />
    <img :src="jsonObj['media:content']['@_url']" alt="full image" />
  </div>
</template>

<script>
import parser from 'fast-xml-parser'

export default {
  asyncData() {
    const xml = `<item>
      <title>Yanii Models | Ben and Ezra</title>
      <link>https://yaniimodels.webflow.io/categories/ben-and-ezra</link>
      <guid>https://yaniimodels.webflow.io/categories/ben-and-ezra</guid>
      <description>Petit Bâteau</description>
      <pubDate>Fri, 16 Jul 2021 16:27:00 GMT</pubDate>
      <media:content url="https://uploads-ssl.webflow.com/60f1911b212fd90baa99ee92/60f1b23cf09c3f73a4f92a1b_b79a66_8fa332a4dea94558b5f1e97200e5cfa7_mv2.jpg" medium="image"/>
      <media:thumbnail url="https://uploads-ssl.webflow.com/60f1911b212fd90baa99ee92/60f1b23cf09c3f73a4f92a1b_b79a66_8fa332a4dea94558b5f1e97200e5cfa7_mv2.jpg"/>
      </item>`
    const jsonObj = parser.parse(xml, { ignoreAttributes: false }).item
    return { jsonObj }
  },
}
</script>

And here is how it looks enter image description here

kissu
  • 40,416
  • 14
  • 65
  • 133