vue.js push array component - javascript

1.vue.js problem component
i want insert a new message in new array with method on click event but
not work for me because function is incomplete
where is the problem.
help me please.
<div class="col-lg-12">
<h1>{{message.title}}</h1>
<h4>{{message.subtitle}}</h4>
</p> {{message.body}}</p>
<button v-on:click="newMessage">Reverse Message</button>
</div>
import {
VueTabs,
VTab
}
from "vue-nav-tabs";
import "vue-nav-tabs/themes/vue-tabs.css";
export default {
components: {
VueTabs,
VTab
},
data() {
return {
title: "elenco",
messages: [{
id: 1,
title: "titolo",
subtitle: "sottotitolo",
body: "argomento",
author: "Amedeo",
date: "17/07/2017",
files: [{
id: 1,
title: "Allegatoriunione",
openfile: "Allegato.pdf"
}, ],
methods: {
newMessage: function() {
this.message.title = this.message.title
.push("")
.split("")
.reverse()
.join("");
}

Your Code Contains many syntax errors which probably fails silently.
Try this new updated code:
<script>
import { VueTabs, VTab } from 'vue-nav-tabs'
import 'vue-nav-tabs/themes/vue-tabs.css'
export default {
components: { VueTabs, VTab },
data() {
return {
title: 'elenco',
messages: [
{
id: 1,
title: 'titolo',
subtitle: 'sottotitolo',
body: 'argomento',
author: 'Amedeo',
date: '17/07/2017',
files: [
{
id: 1,
title: 'Allegatoriunione',
openfile: 'Allegato.pdf'
}
]
}
]
}
},
methods: {
newMessage() {
this.message.title = this.message.title
.push('')
.split('')
.reverse()
.join('')
}
}
}
</script>

Related

Vue - define event handlers in array of dynamic components

I want do create some some different components by looping through an array of components like in my example. But I want to create different event handlers for each component. How can I define them in my componentData Array and bind them while looping?
componentData: [
{ name: TestPane, props: { data: "hello" }, id: 1 },
{ name: TestPane, props: { data: "bye" }, id: 2 },
],
]
<div v-for="component in componentData" :key="component.id">
<component v-bind:is="component.name" v-bind="component.props">
</component>
</div>
You can use the v-on directive. Let's understand how Vue bind your event listeners to the component first:
When you add a #input to a componnet what you are actualy doing is v-on:input. Did you notice the v-on over there? This means that you are actually passing an 'object of listeners' to the component.
Why not pass all of them in one go?
<template>
<section>
<div v-for="component in componentData" :key="component.id">
<component v-bind:is="component.name" v-bind="component.props" v-on="component.on">
</component>
</div>
</section>
</template>
<script>
export default {
data: () => ({
componentData: [
{ name: TestPane, props: { data: "hello" }, id: 1, on: { input: (e) => { console.log(e) } } },
{ name: TestPane, props: { data: "bye" }, id: 2, on: { input: (e) => { console.log(e); } } },
],
})
}
</script>
As you could guess you can listen to the events now inside of on object. You can add more if you would like as well:
{
name: TestPane,
props: { data: "hello" },
id: 1,
on: {
input: (e) => { console.log(e) },
hover: (e) => { console.log('This component was hovered') }
}
}
Add method names to your array like :
componentData: [
{ name: TestPane, props: { data: "hello" }, id: 1, method:"method1" },
{ name: TestPane, props: { data: "bye" }, id: 2 ,method:"method2"},
],
in template :
<component ... #click.native="this[component.method]()">
or add another method called handler which runs the appropriate component method :
<component ... #click.native="handler(component.method)">
methods:{
handler(methodName){
this[methodName]();
}
...
}
if the events are emitted from components, you should add their names and bind them dynamically :
componentData: [
{ name: TestPane, props: { data: "hello" }, id: 1,event:'refresh', method:"method1" },
{ name: TestPane, props: { data: "bye" }, id: 2 ,event:'input',method:"method2"},
],
<component ... #[component.event]="handler(component.method)">

How to run a method using v-for in Vue.js?

I want to get the following output for the following data.
・3
・1
and sample data :
export const dummyData = [
{
id: "1",
name: "a",
sub: [
{
id: "1#1",
name: "b",
sub_sub: [
{ id: "1#1#1", name: "b-a" },
{ id: "1#1#2", name: "b-b" },
]
},
{
id: "1#2",
name: "c",
sub_sub: [
{ id: "1#2#1", name: "c-a" },
]
},
]
},
{
id: "2",
name: "d",
sub: [
{
id: "2#1",
name: "e",
sub_sub: [
{ id: "1#2#1", name: "e-a" },
]
}
]
},
]
I want to count how many elements of sub_sub are includes in object "a" and "d".
So, I made the following code.
<template>
<div>
<ul>
<li v-for="item in items" :key="item.i">{{rowSpanCalc(item.id)}}</li>
</ul>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'nuxt-property-decorator'
import { dummyData } from '~/store/dummy'
#Component({})
export default class extends Vue {
items: any = []
created() {
this.items = dummyData
}
rowSpanCalc(item: any) {
const count = item.sub.reduce(
(total: any, curr: any) => total + curr.sub_sub.length,
0
)
return count;
}
}
</script>
I ran my code and got an error in console like
  
  item.sub.reduce is not a function
Could anyone please advise me how to fix this errors?
Methods in the template are used as events handler not for rendering, try to use that method inside a computed property then use that property for render your items :
#Component({})
export default class extends Vue {
items: any = []
created() {
this.items = dummyData
}
get customItems(){
return this.items.map(item=>({...item,count:this.rowSpanCalc(item.id)}))
}
rowSpanCalc(item: any) {
const count = item.sub.reduce(
(total: any, curr: any) => total + curr.sub_sub.length,
0
)
return count;
}
}
template :
...
<li v-for="item in customItems" :key="item.id">{{item.count}}</li>
...

How do I asynchronously get JSON schema through an API call in react-crud-admin library?

I'm using react-crud-admin library to the generate UI. There is a get_form method that returns JSON schema which is used to create a react form. The method given in the library returns hardcoded JSON schema only. Is there any way to use asynchronous API call to get the schema from a file instead of using a hardcoded schema?
Here's the sample code:
import React from "react";
import Admin from "react-crud-admin";
import Form from "react-jsonschema-form";
import "react-crud-admin/css"; //optional css import
export default class Example extends Admin {
constructor() {
super();
this.name = "Contact";
this.name_plural = "Contacts";
this.list_display_links = ["name"];
this.list_display = ["name", "number", "address.street"];
}
get_queryset(page_number, list_per_page, queryset) {
return [
{
id: 1,
name: "Ken Next",
number: "08939303003",
address: { street: "Hallmark Street" }
},
{
id: 2,
name: "Isa Yoll",
number: "0908839202",
address: { street: "Barbican Street" }
}
];
}
get_form(object = null) {
let schema = {
title: this.name,
type: "object",
required: ["name"],
properties: {
id: {
type: "number",
title: "id",
default: Math.floor(1000 * Math.random()) + 1
},
name: { type: "string", title: "Name", default: "" },
number: { type: "string", title: "Number", default: "" },
address: {
type: "object",
title: "Address",
properties: {
street: { type: "string", title: "Street" }
}
}
}
};
if (!object) {
return <Form schema={schema} />;
} else {
return <Form schema={schema} formData={object} />;
}
}
}
Yes, sure. It is possible. You probably want to implement it in componentDidMount.
import React from "react";
import Admin from "react-crud-admin";
import Form from "react-jsonschema-form";
import "react-crud-admin/css"; //optional css import
export default class Example extends Admin {
constructor() {
super();
this.name = "Contact";
this.name_plural = "Contacts";
this.list_display_links = ["name"];
this.list_display = ["name", "number", "address.street"];
}
get_queryset(page_number, list_per_page, queryset) {
return [
{
id: 1,
name: "Ken Next",
number: "08939303003",
address: { street: "Hallmark Street" }
},
{
id: 2,
name: "Isa Yoll",
number: "0908839202",
address: { street: "Barbican Street" }
}
];
}
get_form(object = null)
if (!object) {
return <Form schema={this.state.schema} />;
} else {
return <Form schema={this.state.schema} formData={object} />;
}
}
componentDidMount()
{
fetch("/url/to/schema").then(response =>{
if(response.ok)
{
response.json().then(schema => this.setState({schema}))
}
});
}
}

Mapping objects in objects [duplicate]

This question already has answers here:
map function for objects (instead of arrays)
(39 answers)
Closed 2 years ago.
I am trying to map and object in React and keep getting the following error
"TypeError: Cannot read property 'map' of undefined"
My Expected Outcome
task-1
task-2
task-3
task-4
Code
import React, { Component } from 'react';
class MapEx extends Component {
constructor(props) {
super(props);
this.state = {
tasks: {
'task-1': { id: 'task-1', content: 'clean house' },
'task-2': { id: 'task-2', content: 'walk dog' },
'task-3': { id: 'task-3', content: 'Do pushups' },
'task-4': { id: 'task-4', content: 'have a drink' }
}
};
}
render() {
const tasks = this.state.tasks
console.log(tasks)
return (
<div>
<h1>Hello</h1>
<p> {this.tasks.map((task) =>
task.id)}</p>
</div>
);
}
}
export default MapEx;
Two issues:
You reference this.tasks instead of this.state.tasks.
You are using map on an object instead of an array.
Try something like this:
return (
<div>
<h1>Hello</h1>
{Object.values(this.state.tasks).map(task => <p>{task.id}</p>)}
</div>
);
map can only be used on arrays. To begin with, convert your data to array DS and proceed as below.
import React, { Component } from 'react';
class MapEx extends Component {
constructor(props) {
super(props);
this.state = {
tasks: {
'task-1': { id: 'task-1', content: 'clean house' },
'task-2': { id: 'task-2', content: 'walk dog' },
'task-3': { id: 'task-3', content: 'Do pushups' },
'task-4': { id: 'task-4', content: 'have a drink' }
}
};
}
render() {
const tasks = this.state.tasks
console.log(tasks)
return (
<div>
<h1>Hello</h1>
{Object.values(tasks).map(task => (<p>{task.id}</p>))}
</div>
);
}
}
export default MapEx;
You can do something like this:
Destructuring state
As tasks is an object you can't map over it, you need to use object.keys
import React, { Component } from 'react';
class MapEx extends Component {
constructor(props) {
super(props);
this.state = {
tasks: {
'task-1': { id: 'task-1', content: 'clean house' },
'task-2': { id: 'task-2', content: 'walk dog' },
'task-3': { id: 'task-3', content: 'Do pushups' },
'task-4': { id: 'task-4', content: 'have a drink' }
}
};
}
render() {
const {tasks} = this.state
console.log(tasks)
return (
<div>
<h1>My tasks</h1>
{!!tasks ? Object.values(tasks).map(task => (<p>{task.id}</p>)) : null}
</div>
);
}
}
export default MapEx;
Working example on https://codesandbox.io/s/react-boilerplate-r68kh
I suggest you to read the docs of map.
It works with arrays and not objects.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
tasks is an object, you need to convert it into an array to make this work.
this.state = {
tasks: [
{ id: 'task-1', content: 'clean house' },
{ id: 'task-2', content: 'walk dog' },
{ id: 'task-3', content: 'Do pushups' },
{ id: 'task-4', content: 'have a drink' }
]
};
You can map over an array and here tasks is an object

Can't retreive my movies data after importing array function in React JS

I can't pass my data from the fakeGenreService.js via array.
Please check the screenshot for the data rendered.
You will see that all things are being rendered, just not (the movie Title, Genre, Stock and Rate) which are available in the fakeGenreService.js
Please do let me know where I am going wrong??????
PLEASE DO LET ME KNOW WHY MY DATA IS NOT BEING RENDERED AND WHAT I NEED TO MAKE THE CHANGES IN THE CODE
I WILL REALLY APPRECIATE YOUR HELP!!!!!!
I am uploading my three files below
App.js
fakeGenreService.js
movies.js
Please check if I am passing the array correctly in the state block?????``
Here is App.js
http://prnt.sc/olccj9
Here is fakegenreService.js
http://prnt.sc/olcdr5
Here is movies.js
http://prnt.sc/olce2x
Here is the final result for the developmentserver
http://prnt.sc/olcejx
Tried various troubsleshooting steps for the array function
This part deals with App.js
import React, { Component } from "react";
import React, { Component } from "react";
import Movies from "./components/movies";
import "./App.css";
class App extends Component {
render() {
return (
<main className="container">
<Movies />
</main>
);
}
}
export default App;
This part is for movies.js
import React, { Component } from "react";
import { getMovies } from "../services/fakeMovieService";
class Movies extends Component {
constructor(props) {
super(props);
this.state = {
movies: [getMovies()]
};
}
handleDelete = movie => {
console.log(movie);
};
render() {
return (
<table className="table">
<thead>
<tr>
<th>Title</th>
<th>Genre</th>
<th>Stock</th>
<th>Rate</th>
<th />
</tr>
</thead>
<tbody>
{this.state.movies.map(movie => (
<tr key={movie._id}>
<td>{movie.title}</td>
<td>{movie.genre}</td>
<td>{movie.numberInStock}</td>
<td>{movie.dailyRentalRate}</td>
<td>
<button
onCick={() => this.handleDelete(movie)}
className="btn btn-danger btn-sm"
>
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
);
}
}
export default Movies;
Here is fakeMovieService.js
import * as genresAPI from "./fakeGenreService";
const movies = [
{
_id: "5b21ca3eeb7f6fbccd471815",
title: "Terminator",
genre: { _id: "5b21ca3eeb7f6fbccd471818", name: "Action" },
numberInStock: 6,
dailyRentalRate: 2.5,
publishDate: "2018-01-03T19:04:28.809Z"
},
{
_id: "5b21ca3eeb7f6fbccd471816",
title: "Die Hard",
genre: { _id: "5b21ca3eeb7f6fbccd471818", name: "Action" },
numberInStock: 5,
dailyRentalRate: 2.5
},
{
_id: "5b21ca3eeb7f6fbccd471817",
title: "Get Out",
genre: { _id: "5b21ca3eeb7f6fbccd471820", name: "Thriller" },
numberInStock: 8,
dailyRentalRate: 3.5
},
{
_id: "5b21ca3eeb7f6fbccd471819",
title: "Trip to Italy",
genre: { _id: "5b21ca3eeb7f6fbccd471814", name: "Comedy" },
numberInStock: 7,
dailyRentalRate: 3.5
},
{
_id: "5b21ca3eeb7f6fbccd47181a",
title: "Airplane",
genre: { _id: "5b21ca3eeb7f6fbccd471814", name: "Comedy" },
numberInStock: 7,
dailyRentalRate: 3.5
},
{
_id: "5b21ca3eeb7f6fbccd47181b",
title: "Wedding Crashers",
genre: { _id: "5b21ca3eeb7f6fbccd471814", name: "Comedy" },
numberInStock: 7,
dailyRentalRate: 3.5
},
{
_id: "5b21ca3eeb7f6fbccd47181e",
title: "Gone Girl",
genre: { _id: "5b21ca3eeb7f6fbccd471820", name: "Thriller" },
numberInStock: 7,
dailyRentalRate: 4.5
},
{
_id: "5b21ca3eeb7f6fbccd47181f",
title: "The Sixth Sense",
genre: { _id: "5b21ca3eeb7f6fbccd471820", name: "Thriller" },
numberInStock: 4,
dailyRentalRate: 3.5
},
{
_id: "5b21ca3eeb7f6fbccd471821",
title: "The Avengers",
genre: { _id: "5b21ca3eeb7f6fbccd471818", name: "Action" },
numberInStock: 7,
dailyRentalRate: 3.5
}
];
export function getMovies() {
return movies;
}
export function getMovie(id) {
return movies.find(m => m._id === id);
}
export function saveMovie(movie) {
let movieInDb = movies.find(m => m._id === movie._id) || {};
movieInDb.name = movie.name;
movieInDb.genre = genresAPI.genres.find(g => g._id === movie.genreId);
movieInDb.numberInStock = movie.numberInStock;
movieInDb.dailyRentalRate = movie.dailyRentalRate;
if (!movieInDb._id) {
movieInDb._id = Date.now();
movies.push(movieInDb);
}
return movieInDb;
}
export function deleteMovie(id) {
let movieInDb = movies.find(m => m._id === id);
movies.splice(movies.indexOf(movieInDb), 1);
return movieInDb;
}
The result of the data being rendered is shown here:
http://prnt.sc/olcejx
Please let me know how could the movies defined in getMovies() function coud be rendered in the table.
The issue seems to be here. getMovies would already return an array. You're wrapping it inside another one. Here, in yout Movies Component class, change it to just the function call:
constructor(props) {
super(props);
this.state = {
movies: getMovies() // [getMovies()]
};
}
You wrap the movies array into a second array. That does not work. You should write it like this :
this.state = {
movies: getMovies()
};
getMovies() already returning array. You are calling that function inside an array. so movies have an array of array. like this movies: [[datas]].
In movies.js file do this changes in the constructor. It should work.
this.state = {
movies: getMovies();
}

Categories

Resources