Passing an array to a component in Vue.js 2.0 - javascript

I am passing an array to a component in Vue.js but it is not passing properly. Strings pass fine. My code is below:
Vue code
<template>
<div class="panel panel-default">
<div class="panel-heading">{{c}}</div>
<div class="panel-body">
</div>
</div>
</template>
<script>
import axios from 'axios';
export default {
mounted() {
console.log('Component ready.');
},
props: ['f','c'],
data : function() {
return {
}
},
And the HTML/PHP
<div class="container">
<div class="row">
<div class="col-md-12">
<?php $a = ['Pasta', 'Chicken', 'Rice']; ?>
<credits f= $a c="One"></credits>
</div>
</div>
</div>
In this case "c" works fine and "f" doesn't.
How can I do this properly?

Maybe try to encode the value using json_encode()like this:
<credits f="<?= json_encode($a)?>" c="One"></credits>

Related

Javascript - How to search no matter upperCase or lowercase in Vue.js?

I m using Vue.js 3 and here I have search in data, but this data is from a fake API. So this search works only for small or big characters, but I want to search throw data no matter uppercase or lowercase?
Here is my code
<template>
<div class='home'>
<h1>Third</h1>
<div v-if="error"> {{error}} </div>
<div v-if="posts.length">
<input type="text" v-model.trim="search" />
<!-- <p>search term - {{search}}</p> -->
<div v-for="post in matchingNames" :key='post.id'>
<h3>{{post.title }}</h3>
<h1>{{post.id}}</h1>
</div>
</div>
<div v-else> Loading...</div>
</div>
</template>
<script>
import { computed, ref, watch, watchEffect} from 'vue'
// import Listing from '../components/Listing.vue'
import getPosts from '../composables/getPosts'
export default {
name:'Third',
components: {} ,
setup(){
const search = ref('')
const{posts,error,load} = getPosts()
load()
const matchingNames = computed (()=> {
return posts.value.filter((post)=>post.title.match(search.value))
})
return {posts, error, search, matchingNames}
}
}
</script>
<style>
</style>
I also tried to replace match method with includes js method but the result is the same
This is a gif of how that now works, can anyone help me I'm new at Vue.js 3
Convert both to lowercase first :)
...
return posts.value.filter((post)=>post.title.toLowerCase().includes(search.value.toLowerCase()))
...

Vuejs SearchBar ||using filter method not working

I quite new to Vue js I am trying to use the computed method to create a search bar to only search through the name but I'm getting "this.info.filter" is not a function
<template>
<div class="container">
<input type="text" v-model="search" placeholder="Search by name">
<div class="content" v-for="student in filterName " v-bind:key="student.id">
<img class="image" :src="student.pic" alt="">
<div class="student-info">
<h1 class="info">{{student.firstName +" "+ student.lastName}}</h1>
<div class="infomation">
<p class="cop">{{ student.company }}</p>
<p class="ski">{{ student.skill }}</p>
<p class="email">{{ student.email }}</p>
<p class="grade">{{ student.grades }}</p>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from "axios";
export default {
name: "Student.vue",
data() {
return {
students: '',
search: ''
}
},
mounted() {
axios
.get('https://api.hatchways.io/assessment/students')
.then((res) => {
this.students = (res.data.students)
})
},
computed :{
filterName:function (){
return this.info.filter((student)=>{
return student.company.matcth(this.search);
})
}
}
}
</script>
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
First time using StackOverflow too please ignore the errors
I don't see a declaration/initialization for this.info anywhere in your code.
The reason you're getting that error is because filter is trying to run on an undefined variable (this.info is undefined).
You might want to initialize that to an empty array within data.

How can I generate random item on button click?

I have a component that generates a random item every time I access the random page. Each time I refresh the page a new random item is generated. I would like to generate a new random item every time I click the button 'pick another', but I'm not entirely sure how this can be done. Any help would be greatly appreciated.
Random.vue
<template>
<div class="details" v-for="item in items" v-bind:key="item.id">
<div class="details-primary u-center-text">
<h1 class="heading-secondary">{{item.name}}</h1>
<p class="tagline--main">{{item.tagline}}</p>
</div>
<div class="details-secondary u-margin-top-big">
<div class="info">
<span class="info__detail info--title">Vol</span>
<span class="info__detail info--spec">{{item.abv}}%</span>
</div>
<img class="details-image" :src='item.image_url' alt="">
<div class="info">
<span class="info__detail info--title">Amount</span>
<span class="info__detail info--spec">1ltr</span>
</div>
</div>
</div>
<div class="rand-gen">
Pick another
</div>
</template>
<script lang="ts">
import {Options, Vue} from 'vue-class-component'
import axios from 'axios';
#Options({
data() {
return{
items: []
}
},
mounted() {
axios.get('https://api.punkapi.com/v2/beers/random')
.then(res => this.items = res.data)
.catch(err => console.log(err));
}
})
export default class Random extends Vue {}
</script>
you have to add #click function and method
html should like this
Pick another
and the method is
methods: {
generate() {
//your code
}
}

VUE- How do I put the values inside of components imported?

I remember I have seen once how to put the values in the html text area after importing components in VUE.
I'm not sure there is a way to do that or I just remember things in a wrong way.
my code is as below.
<template>
<div class="container">
<div class="row">
<Heading></Heading>
</div>
<hr>
<div class="row">
<div class="col-xs-12 col-sm-6">
<ul class="list-group">
<comp v-for='(value,index) in listing' :key='index'>{{value}}</comp>
</ul>
</div>
<serverstat></serverstat>
</div>
<hr>
<div class="row">
<footing></footing>
</div>
</div>
</template>
<script>
import Heading from './assets/Heading.vue';
import comp from './assets/comp.vue';
import serverstat from './assets/serverstatus.vue';
import footing from'./assets/footing.vue';
export default {
data() {
return {
listing: ['max','toms','judy','michael','dumdum']
}
},
components: {
Heading,comp,serverstat,footing
},
};
</script>
<style>
</style>
-comp-
<template>
<li class="list-group-item">
</li>
</template>
<script>
export default {
}
</script>
<style>
</style>
After I render this,
it doesn't show {{value}}. It only shows blank .
How do I insert the {{value}} within the html element?
Thank you in advance.
Since you are entering a value inside of a component, you can render it by using a slot in your component like this:
<template>
<li class="list-group-item">
<slot />
</li>
</template>
<comp v-for='(value,index) in listing' :key='index'>
<slot>{{ value }} </slot>
</comp>
Then in comp component use slot as
<slot/>
Not including the approach for props as you don't want to use that. Use the link above to learn more about slots.
When you use v-for it calls all the value from an array and :key='index' defines each object row from an array. If your object listing consists of firstname, lastname as your object then the value you want to print will be {{value.firstname}}. You are missing object name in value.
Can you try this once :
<comp v-for='(value,index) in listing' :key='index'>{{value.index}}</comp>

Passing data from parent component to a child component

I have a parent component as follows
<template>
<div class="row">
<mappings mapping-list="{{currentMappings}}"></mappings>
</div>
</template>
<script>
import Mappings from './content/Mappings.vue';
export default {
data () {
return {
currentMappings: Array
}
},
created () {
this.readData();
},
methods: {
readData () {
this.$http.get('data/Books.xml').then((response)=> {
var x2js = new X2JS();
var jsonObj = x2js.xml_str2json( response.body );
this.getMappings(jsonObj.WAStatus);
});
},
getMappings (jsonObj) {
this.currentMappings = jsonObj.WSSMappings;
}
},
components: { Mappings }
};
</script>
and a child "mappings" component as follows
<template>
<div class="col-lg-4">
<div class="hpanel stats">
<div class="panel-body h-200">
<div class="stats-title pull-left">
<h3>Mappings</h3>
</div>
<div class="stats-icon pull-right">
<img src="images/mappings.png" class="browserLogo">
</div>
<div class="m-t-xl">
<table class="table table-striped table-hover">
<tr v-for="mapping in mappingList ">
<td>name - {{$index}}</td>
</tr>
</table>
</div>
</div>
<div class="panel-footer">
Current WSS - SA Mappings
</div>
</div>
</div>
</template>
<script>
export default {
props: {
mappingList:Array
},
created () {
console.log(this.mappingList);
// console.log(this.$parent.mappings);
}
}
</script>
I am unable to pass data from the parent component to the child component. I am trying to use props here. The error that I am getting is
main.js:2756[Vue warn]: Invalid prop: type check failed for prop "mappingList". Expected Array, got String. (found in component: <mappings>)
Update
As per the suggestions made I have updated the parent component as follows
<template>
<div class="row">
<browser-stats></browser-stats>
</div>
<div class="row">
<mappings :mapping-list="currentMappings"></mappings>
</div>
</template>
<script>
import Mappings from './content/Mappings.vue';
export default {
data () {
return {
currentMappings: []
}
},
created () {
this.readData();
},
methods: {
readData () {
this.$http.get('data/WA_Status.xml').then((response)=> {
var x2js = new X2JS();
var jsonObj = x2js.xml_str2json( response.body );
this.getMappings(jsonObj.WAStatus);
});
},
getMappings (jsonObj) {
this.currentMappings = jsonObj.WSSMappings;
console.log(this.currentMappings.length);
console.log(JSON.stringify(this.currentMappings));
}
},
components: { Mappings }
};
</script>
and the child "mappings" component as follows
<template>
<div class="col-lg-4">
<div class="hpanel stats">
<div class="panel-body h-200">
<div class="stats-title pull-left">
<h3>Mappings</h3>
</div>
<div class="stats-icon pull-right">
<img src="images/mappings.png" class="browserLogo">
</div>
<div class="m-t-xl">
<table class="table table-striped table-hover">
<tr v-for="mapping in mappingList ">
<td>{{mapping._name}}</td>
</tr>
</table>
</div>
</div>
<div class="panel-footer">
Current WSS - SA Mappings
</div>
</div>
</div>
</template>
<script>
export default {
props: {
mappingList:[]
}
}
</script>
but I am getting an empty mappingList which means whenever I am doing console.log(this.currentMappings.length); I get undefined..
Can you please let me know what I am doing wrong here ?
Thanks
1) Fist issue
data () {
return {
currentMappings: Array
}
Should be
data () {
return {
currentMappings: []
}
2) Second issue
<mappings mapping-list="{{currentMappings}}"></mappings>
Should be:
<mappings :mapping-list="currentMappings"></mappings>
3) Third issue
created () {
console.log(this.mappingList);
// console.log(this.$parent.mappings);
}
This will return empty array every time. Because mappingList changed via AJAX and it's happed after created() was called. Try to use vue-devtool (chrome plugin) for better debug experience.
UPDATED:
To be able to watch async changes (like made with AJAX) consider to use watch this way:
{
data(){
//..
},
watch:{
'currentMappings'(val){
console.log('currentMappings updated', currentMappings);
}
}
}
Docs are here.
You use string interpolation ({{ }}) to try and pass the data to the prop - but the interpolation will turn the array into a string.
You should use a binding with v-bind
<mappings v-bind:mapping-list="currentMappings"></mappings>
...short form:
<mappings :mapping-list="currentMappings"></mappings>

Categories

Resources