How to add content that is coming from an AJAX call

Ionic version: 6.18.2
Framework: Ionic React

I’m struggling to make an AJAX call work. How can I add content that is coming from an AJAX call with Ionic React?

Here is my AJAX call to get content from another website:

  $.ajax({
    method: "GET",
    url: "https://www.my-website.ch/api/data"
  })
  .done(function( content ) {
    console.log(content)
  });

Since this is an AJAX call, the content is not immediately available. What I usually do is to append the incoming content to a class, like this:

  <div className="target">
  </div>
  {get_items()}
function get_items(){
  $.ajax({
  method: "GET",
  url: "https://www.my-website.ch/api/data"
})
  .done(function( content ) {
    console.log(content)

    $(".target").append(
      `
      <IonCard>
        <IonCardHeader>
          <IonCardSubtitle></IonCardSubtitle>
          <IonCardTitle className="ion-text-center">${content[0].name}</IonCardTitle>
        </IonCardHeader>

        <IonCardContent>
        <div className="center">
          ${content[0].company}
          </div>
      </IonCardContent>
      </IonCard>
      `
    );

  });
}

But if I do it this way, the components are not rendered correctly. Only the text itself is appended, but not the IonCard with its styling. Also, the text gets appended twice, not once.

I believe that the text gets appended twice, because there is a shadow-root where there is another div with the class “target”. I think that my usual approach does not work for Ionic Apps.

What is the correct way to do this? How do I add content in Ionic React that is coming from an AJAX call? Or in my case: How do I add another IonCard when the content arrives?

And using jquery with any framework is not a great idea

The append jquery will not work because what you try to add isnt js but React code which wont get transpiled to js in runtime

Can you get rid of jquery at all and find the React equivalent way?

Ah, React has it’s own way to update its component. Thank you very much for your time and effort.

Here is my solution:

import React, { useEffect, useState } from 'react';
import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar, IonCard, IonCardHeader, IonCardSubtitle, IonCardTitle, IonCardContent, IonItem, IonIcon, IonLabel, IonButton, IonImg } from '@ionic/react';


const Items: React.FC = () => {

  const [error, setError] = useState(null);
  const [isLoaded, setIsLoaded] = useState(false);
  const [items, setItems] = useState([]);

  // Note: the empty deps array [] means
  // this useEffect will run once
  // similar to componentDidMount()
  useEffect(() => {
    fetch("https://www.my-website.api.com)
      .then(res => res.json())
      .then(
        (result) => {
          console.log(result);
          setIsLoaded(true);
          setItems(result);
        },
        // Note: it's important to handle errors here
        // instead of a catch() block so that we don't swallow
        // exceptions from actual bugs in components.
        (error) => {
          setIsLoaded(true);
          setError(error);
        }
      )
  }, [])

  if (error) {
    return <div>Error: </div>;
  } else if (!isLoaded) {
    return <div>Loading...</div>;
  } else {
    return (
      <div>

      {items.map(item => (
        <IonCard>
          <IonCardHeader>
            <IonCardSubtitle></IonCardSubtitle>
            <IonCardTitle className="ion-text-center">{item["company"]}</IonCardTitle>
          </IonCardHeader>

          <IonCardContent>
          <div className="center">
            {item["content"]}
          </div>
          <hr />
          <div className="center">
            {item["offer"]}
          </div>
        </IonCardContent>
        </IonCard>
      ))}
      </div>
    );
  }
};

export default Items;
1 Like