Using REST API with Vue

User
use rest api in vue js
Assistant
In Vue.js, you can use REST APIs by making HTTP requests using `fetch` or `Axios`. Since you're already using Axios in your project, I'll focus on that approach.

### **Steps to Use REST API in Vue.js (with Axios)**

#### **1. Install Axios (if not installed)**
Since you're using Yarn, run:

yarn add axios

Or with npm:

npm install axios

#### **2. Make an API Request in Vue Component**
Here's an example of fetching data from an API in a Vue 3 component:

<script setup>
import { ref, onMounted } from "vue";
import axios from "axios";

const posts = ref([]);
const loading = ref(true);
const error = ref(null);

const fetchPosts = async () => {
  try {
    const response = await axios.get("https://jsonplaceholder.typicode.com/posts");
    posts.value = response.data;
  } catch (err) {
    error.value = "Error fetching posts";
  } finally {
    loading.value = false;
  }
};

onMounted(fetchPosts);
</script>

<template>
  <div>
    <h2>Posts</h2>
    <p v-if="loading">Loading...</p>
    <p v-if="error">{{ error }}</p>
    <ul v-if="!loading && !error">
      <li v-for="post in posts" :key="post.id">{{ post.title }}</li>
    </ul>
  </div>
</template>

#### **3. Make a POST Request**
To send data to an API:

<script setup>
import { ref } from "vue";
import axios from "axios";

const newPost = ref({
  title: "",
  body: "",
});

const submitPost = async () => {
  try {
    const response = await axios.post("https://jsonplaceholder.typicode.com/posts", newPost.value);
    console.log("Post created:", response.data);
  } catch (err) {
    console.error("Error creating post:", err);
  }
};
</script>

<template>
  <form @submit.prevent="submitPost">
    <input v-model="newPost.title" placeholder="Title" required />
    <textarea v-model="newPost.body" placeholder="Body" required></textarea>
    <button type="submit">Submit</button>
  </form>
</template>

### **4. Create an Axios Instance (For Global Use)**
Instead of calling `axios.get()` directly everywhere, you can create a reusable instance:

import axios from "axios";

const api = axios.create({
  baseURL: "https://jsonplaceholder.typicode.com",
  headers: {
    "Content-Type": "application/json",
  },
});

export default api;

Then use it in your components:

import api from "@/api"; // Adjust the path accordingly

api.get("/posts").then(response => {
  console.log(response.data);
});

### **5. Handle Authentication (Example: Bearer Token)**
If your API requires authentication:

const api = axios.create({
  baseURL: "https://api.example.com",
  headers: {
    Authorization: `Bearer ${localStorage.getItem("token")}`,
  },
});

Let me know if you need help integrating this with your Laravel backend! ๐Ÿš€

User
add post link
Assistant
To add a **post link** in your Vue.js component, you can modify the template to include a clickable link for each post. Assuming the API provides a `post.id`, you can generate links dynamically.

### **Updated Vue Component with Post Links**

<script setup>
import { ref, onMounted } from "vue";
import axios from "axios";

const posts = ref([]);
const loading = ref(true);
const error = ref(null);

const fetchPosts = async () => {
  try {
    const response = await axios.get("https://jsonplaceholder.typicode.com/posts");
    posts.value = response.data;
  } catch (err) {
    error.value = "Error fetching posts";
  } finally {
    loading.value = false;
  }
};

onMounted(fetchPosts);
</script>

<template>
  <div>
    <h2>Posts</h2>
    <p v-if="loading">Loading...</p>
    <p v-if="error">{{ error }}</p>
    <ul v-if="!loading && !error">
      <li v-for="post in posts" :key="post.id">
        <a :href="`/posts/${post.id}`" target="_blank">{{ post.title }}</a>
      </li>
    </ul>
  </div>
</template>

### **Explanation:**
– The “ tag dynamically generates a link using `:href="`/posts/${post.id}`"`.
– Clicking the link will navigate to `/posts/{id}`, assuming you have a route set up for post details.
– `target="_blank"` opens the link in a new tab.

### **Bonus: Using Vue Router for Navigation**
If you're using **Vue Router**, update the links like this:

<RouterLink :to="`/posts/${post.id}`">{{ post.title }}</RouterLink>

And define a route in your `router.js`:

{
  path: "/posts/:id",
  name: "PostDetails",
  component: () => import("@/views/PostDetails.vue")
}

This way, clicking a post title navigates within the Vue app without a full page reload. ๐Ÿš€

User
external url
Assistant
If you want the post link to open an **external URL** instead of an internal route, you need to ensure your API provides a `url` field or construct the URL properly.

### **Example: Linking to an External URL**
Modify the Vue component to use an **external link**:

<script setup>
import { ref, onMounted } from "vue";
import axios from "axios";

const posts = ref([]);
const loading = ref(true);
const error = ref(null);

const fetchPosts = async () => {
  try {
    const response = await axios.get("https://jsonplaceholder.typicode.com/posts");
    posts.value = response.data.map(post => ({
      ...post,
      url: `https://example.com/posts/${post.id}`, // Replace with actual external URL logic
    }));
  } catch (err) {
    error.value = "Error fetching posts";
  } finally {
    loading.value = false;
  }
};

onMounted(fetchPosts);
</script>

<template>
  <div>
    <h2>Posts</h2>
    <p v-if="loading">Loading...</p>
    <p v-if="error">{{ error }}</p>
    <ul v-if="!loading && !error">
      <li v-for="post in posts" :key="post.id">
        <a :href="post.url" target="_blank" rel="noopener noreferrer">{{ post.title }}</a>
      </li>
    </ul>
  </div>
</template>

### **Key Changes:**
1. **Dynamically generate the external URL** (e.g., `https://example.com/posts/${post.id}`).
2. **Use “ with `target="_blank"`** to open the link in a new tab.
3. **Add `rel="noopener noreferrer"`** for security when opening external links.

#### **If Your API Provides the External URL**
If your API response already includes an external URL (e.g., `post.external_url`), modify the mapping:

posts.value = response.data.map(post => ({
  ...post,
  url: post.external_url, // Use the actual external URL from API
}));

This way, your Vue app dynamically links to external posts without hardcoding URLs. ๐Ÿš€

User
limit post excerpt to 100 char
Assistant
To limit the post excerpt to **100 characters**, you can use Vue's computed properties or simple string slicing inside the template.

### **Updated Vue Component with Excerpt Limiting**

<script setup>
import { ref, onMounted, computed } from "vue";
import axios from "axios";

const posts = ref([]);
const loading = ref(true);
const error = ref(null);

const fetchPosts = async () => {
  try {
    const response = await axios.get("https://jsonplaceholder.typicode.com/posts");
    posts.value = response.data.map(post => ({
      ...post,
      excerpt: post.body.length > 100 ? post.body.substring(0, 100) + "..." : post.body, // Limit to 100 characters
      url: `https://example.com/posts/${post.id}`, // Replace with actual external URL logic
    }));
  } catch (err) {
    error.value = "Error fetching posts";
  } finally {
    loading.value = false;
  }
};

onMounted(fetchPosts);
</script>

<template>
  <div>
    <h2>Posts</h2>
    <p v-if="loading">Loading...</p>
    <p v-if="error">{{ error }}</p>
    <ul v-if="!loading && !error">
      <li v-for="post in posts" :key="post.id">
        <h3>
          <a :href="post.url" target="_blank" rel="noopener noreferrer">{{ post.title }}</a>
        </h3>
        <p>{{ post.excerpt }}</p>
      </li>
    </ul>
  </div>
</template>

### **Key Changes:**
1. **Added an excerpt property in `map()`**:
– Limits the body to 100 characters.
– Adds `"…"` if the text is longer.

2. **Displays the excerpt in `{{ post.excerpt }}`**.

This ensures your post descriptions stay concise while linking to full content. ๐Ÿš€

Leave a Comment

Your email address will not be published. Required fields are marked *