i want to build a search with ajax and vue.
So i have a model called "file" here all my files
then i have a controller called searchcontroller.php
public function search(Request $request)
{
$files = File::where('name', $request->keywords)->get();
return response()->json($files);
}
this is my route
Route::post('/', 'SearchController#search');
and i have a search.vue
<template>
<div>
<input type="text" v-model="keywords">
<ul v-if="results.length > 0">
<li v-for="result in results" :key="result.id" v-text="result.name"></li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
keywords: null,
results: []
};
},
watch: {
keywords(after, before) {
this.fetch();
}
},
methods: {
fetch() {
axios.get('/', { params: { keywords: this.keywords } })
.then(response => this.results = response.data)
.catch(error => {});
}
}
}
</script>
if i type a letter the resposce work i think but it shows me 10000 list points with an emtpy result
i wanna do it like here: https://jsfiddle.net/hej7L1jy/2/
if i do:
console.log(this.results);
console.log(this.keywords);
i get for results:
Array(0)
and the keyword works
public function search(Request $request)
{
$files = File::where('name', 'like', '%' . $request->get('keywords') . '%')->get();
return response()->json($files);
}
<template>
<div>
<input type="text" v-model="keywords">
<ul v-if="results.length > 0">
<li v-for="result in results" :key="result.id">{{ result.name }}</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
keywords: null,
results: []
};
},
watch: {
keywords(after, before) {
this.fetch();
}
},
methods: {
fetch() {
axios.post('/', { params: { keywords: this.keywords } })
.then(response => this.results = response.data)
.catch(error => {});
}
}
}
</script>
I GOT IT :)
Controller:
public function search(Request $request)
{
$files = DB::table('files')->where('name', 'like', '%' . $request->get('keywords') . '%')->get();
return response()->json($files);
}
Route:
Route::get('/search', 'SearchController#search');
Vue:
<template>
<div>
<input type="text" v-model="keywords">
<ul v-if="results.length > 0">
<li v-for="result in results" :key="result.id">{{ result.name }}</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
keywords: null,
results: []
};
},
watch: {
keywords(after, before) {
this.fetch();
}
},
methods: {
fetch() {
axios.get('/search', { params: { keywords: this.keywords } })
.then(response => this.results = response.data)
.catch(error => {});
}
}
}
</script>
i edited the where function in my controller and i needed a "get" method , not a "post" :)
Related
I would like to fetch and display data on load. After this I would like to display data on search.
Now I only manage to display data on search keyup. I would like to show the list of artist when loading the page as well.
How to display data on load page
How to display data on search
Thanks in advance!
<template>
<div class="body">
<div class="searchBar">
<i class="bi bi-search"></i>
<input
placeholder="Search for artists"
type="text"
v-model="searchQuery"
#keyup="searchArtist"
/>
</div>
<div class="artists">
<div
className="artist__list"
v-for="artistResult in result"
:key="artistResult.id"
>
<h4>{{ artistResult.name }}</h4>
</div>
</div>
</div>
</template>
<script>
import axios from "axios";
import "./body.css";
export default {
data() {
return {
artists: [],
result: [],
searchQuery: "",
};
},
mounted() {
this.fetchArtists();
},
computed: {
filteredResult() {
const res = this.result;
const search = this.searchQuery;
if (!search) {
return res;
}
return res.filter((item) =>
item.name.toLowerCase().includes(search.toLowerCase())
);
},
},
methods: {
searchArtist() {
axios
.get(`http://localhost:3000/artists?q=${this.searchQuery}`)
.then((response) => {
this.result = response.data;
})
.catch((error) => {
console.error(error);
});
},
fetchArtists() {
axios
.get("http://localhost:3000/artists")
.then((response) => {
this.artists = response.data;
})
.catch((error) => {
console.error(error);
});
},
},
};
</script>
On fetch I need it to bind the api response to the empty array result.
return {
result: [],
searchQuery: "",
};
},
fetchArtists() {
axios
.get("http://localhost:3000/artists")
.then((response) => {
this.result = response.data;
})
.catch((error) => {
console.error(error);
});
},
import axios from "axios";
export const routerid = async (itemId) =>
await axios.get("https://fakestoreapi.com/products?limit=" + itemId);
<template>
<div>
<div v-for="(item, key) in user" :key="key">
{{ item.price }} <br />
{{ item.description }} <br />
</div>
</div>
</template>
<script>
import { routerid } from "./routerid";
export default {
name: "User",
components: {},
data() {
return {
lists: [],
};
},
mounted() {
if (this.$route.params.id)
routerid(this.$route.params.id).then((r) => {
let obj = r.data;
this.lists = [{ ...obj }];
});
},
computed: {
user: function () {
return this.lists.filter((item) => {
return item.id === this.$route.params.id;
});
},
},
};
</script>
And this is my complete code:- https://codesandbox.io/s/late-brook-eg51y3?file=/src/components/routerid.js
Above is my api call, with url query like url...../?limit=" + id
Above is the logic , which i tried. But not sure whats wrong with code. getting blank screen.
please provide some suggestions, on how to call. and please go through my code once, if there is any other issues. Thanks
It's all about spread operator, you should spread object inside array correctly, below example works fine.
<template>
<div>
<div v-for="(item, key) in user" :key="key">
{{ item.price }} <br />
{{ item.description }} <br />
</div>
</div>
</template>
<script>
import { routerid } from "./routerid";
export default {
name: "User",
components: {},
data() {
return {
lists: [],
};
},
mounted() {
if (this.$route.params.id)
routerid(this.$route.params.id).then((r) => {
let obj = r.data;
//changed from [{...obj}] to [...obj]
this.lists = [...obj];
});
},
computed: {
user: function () {
return this.lists.filter((item) => {
return item.id === this.$route.params.id;
});
},
},
};
</script>
You have 2 problems.
1 - Firstly you're using user instead of lists in the for loop.
2 - Secondly you're using spread operator on the retuned data which is already an array so you don't need to do that.
<template>
<div>
<div v-for="(item, key) in lists" :key="key">
{{ item.price }} <br />
{{ item.description }} <br />
</div>
</div>
</template>
<script>
import { routerid } from "./routerid";
export default {
name: "User",
components: {},
data() {
return {
lists: [],
};
},
mounted() {
if (this.$route.params.id)
routerid(this.$route.params.id).then((r) => {
this.lists = r.data;
});
},
computed: {
user: function () {
return this.lists.filter((item) => {
return item.id === this.$route.params.id;
});
},
},
};
</script>
I'm creating a page for an App with the Quasar Framework, how do I consume this Api on the Quasar page (template)?
Could you help me make a v-for on the cards? How would you get the (articles title) of this object.
Quasar version 1.0, axios plugin.
Html:
<div class="" v-for="(articles, index) in posts" :key="index">
{{ articles.title }}
</div>
<script>
export default {
name: 'Novidades',
data () {
return {
posts: []
}
},
mounted () {
this.getPosts()
},
methods: {
getPosts () {
this.$axios.get('https://newsapi.org/v2/everything?q=bitcoin&from=2019-05-04&sortBy=publishedAt&apiKey=4feb77b8660e4904a51ecbcae805ce03')
.then((resp) => {
this.posts = resp.data
})
.catch((err) => {
console.error(err)
})
}
}
}
</script>
Ok. It seems that is a problem with how you manipulate JSON that you received.
It's easy to see that you have an array inside object received that is called "articles". And each element has a title. So basically what you have to do is, get this articles and v-for inside of it.
The code could be like
<template>
<div>
<div v-for="(article, index) in articles" :key="index">{{ article.title }}</div>
</div>
</template>
<script>
export default {
name: "Novidades",
data() {
return {
articles: []
};
},
mounted() {
this.getArticles();
},
methods: {
getArticles() {
this.$http
.get(
"https://newsapi.org/v2/everything?q=bitcoin&from=2019-05-04&sortBy=publishedAt&apiKey=4feb77b8660e4904a51ecbcae805ce03"
)
.then(resp => {
this.articles = resp.data.articles;
})
.catch(err => {
console.error(err);
});
}
}
};
</script>
And the code is running in here: https://codesandbox.io/s/vue-template-wf6tr
On the change of the value id, I would like to make a JSON call via Axios and update necessary parts of the page. How do I do that? Currently, I have mounted and activated and they do not seem to be working...
Code:
const Home = {
template: `
<div class="user">
<h2>user {{ id }}</h2>
<h2>{{ info }}</h2>
bet
</div>
`,
props: {
id: {
type: String,
default: 'N/A'
}
},
data () {
return {
info: null
}
},
activated () {
axios
.get('https://api.coindesk.com/v1/bpi/currentprice.json',
{ params: { id: id }}
)
.then(response => (this.info = response))
},
mounted() {
axios
.get('https://api.coindesk.com/v1/bpi/currentprice.json')
.then(response => (this.info = 'response'))
}
}`
You can listen to id prop change by using watch:
watch: {
id: function(newId) {
axios
.get('https://api.coindesk.com/v1/bpi/currentprice.json',
{ params: { id: newId }}
)
.then(response => (this.info = response))
}
}
Here is a little demo based on the code that you shared that shows how watch reacts to id prop change. Wrapper component below is solely for demonstration purpose as something that triggers id value change.
const Home = {
template: `
<div class="user">
<h2>user {{ id }}</h2>
<h2>{{ info }}</h2>
bet
</div>
`,
props: {
id: {
default: 'N/A'
}
},
data () {
return {
info: null
}
},
mounted() {
axios
.get('https://api.coindesk.com/v1/bpi/currentprice.json')
.then(response => (this.info = 'response'))
},
watch: {
id: function(newId) {
console.log(`watch triggered, value of id is: ${newId}`);
axios
.get('https://api.coindesk.com/v1/bpi/currentprice.json',
{ params: { id: newId }}
)
.then(response => (this.info = response))
}
}
}
const Wrapper = {
template: '<div><home :id="id" /></div>',
components: { Home },
data() {
return {
id: 0
}
},
mounted() {
const limit = 5;
const loop = (nextId) => setTimeout(() => {
console.log(`#${nextId} loop iteration`);
if (nextId < limit) {
this.id = nextId;
loop(nextId + 1);
}
}, 3000);
loop(this.id);
}
}
new Vue({
el: '#app',
components: { Wrapper }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js" ></script>
<div id="app">
<wrapper />
</div>
How do pass errors from ajax to error-form component?
FormLink.vue component:
<template>
<error-form></error-form>
<form class="form-horizontal">
.
.
</form>
</template>
<script>
export default {
methods: {
addLink: function (event) {
event.preventDefault();
this.$http.post('/user/link', {name: this.linkName, key: this.linkValue}).then(response => {
this.users.links.push(response.json());
this.linkName = '';
this.linkValue = '';
}).error(function(errors) {
// how to pass errors data to <error-form> component?
});
},
}
}
</script>
ErrorForm.vue component
<template>
<div class="alert alert-danger">
<strong>Errors!</strong><br><br>
<ul>
<li></li>
</ul>
</div>
</template>
<script>
export default {
ready() {
console.log('Error Component ready.');
},
data: function () {
return {
}
},
}
</script>
in App.js
Vue.component('form-link', require('./components/Profile/FormLink.vue'));
Vue.component('error-form', require('./components/Global/ErrorForm.vue'));
Pass your data using props:
FormLink Component:
<template>
<error-form :errors="errors"></error-form>
</template>
<script>
EXPORT default {
data() {
return {
errors: []
}
},
methods: {
addLink: function (event) {
event.preventDefault();
this.$http.post('/user/link', {name: this.linkName, key: this.linkValue}).then(response => {
this.users.links.push(response.json());
this.linkName = '';
this.linkValue = '';
}).error(function(errors) {
this.errors = errors;
});
},
}
}
</script>
ErrorForm Component:
<template>
<div class="alert alert-danger">
<strong>Errors!</strong><br><br>
<ul>
<li v-for="error in errors">{{ error }}</li>
</ul>
</div>
</template>
<script>
EXPORT default {
props: {
errors: Array
},
ready() {
console.log('Error Component ready.');
},
data: function () {
return {
}
},
}
</script>