dynamic V-for shows no result (Vue.js) - html

I'm trying to fill an array with a list of objects that comes from an api, the objects are coming normally, but when trying to move to the array and play in the v-for nothing appears.
Here's my data vars:
data() {
return {
elementsReport: [],
};
},
Here's my "computed" section:
computed: {
changeElements: {
get() {
return this.elementsReport;
},
set() {
return this.elementsReport;
}
}
}
Here's my api call:
this.elementsReport = this.getHistoryDeliveryPositionsByDriverIdAndDateAPI();
Here's my api function:
getHistoryDeliveryPositionsByDriverIdAndDateAPI() {
axios
.post("/web-api/reports/history-delivery-position/generate", {
driver_id: this.driver,
initial_date: this.initialDate,
final_date: this.finalDate
})
.then(({ data }) => {
_this.elementsReport = data;
})
.catch(function() {
alert("Erro ao filtrar relatórios");
});
}
Here's my html table with the v-for:
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
</tr>
</thead>
<tbody>
<tr v-for="elements in changeElements">
<td scope="row">{{elements.id}}</td>
<td></td>
</tr>
</tbody>
</table>

Have you tried to bind the key prop to the tr element?
Like this:
<tr v-for="elements in elementsReport" :key="elements.id">
<td scope="row">{{elements.id}}</td>
<td></td>
</tr>

Lots of things wrong with your code. I would recommend using tutorials to learn JavaScript and Vue.
1) There is no need for a computed here. Use elementsReport in the template.
<tr v-for="elements in elementsReport" :key="elements.id">
<td scope="row">{{elements.id}}</td>
<td></td>
</tr>
2) Your API function is wrong, and you are trying to set elementsReport twice. It should be:
getHistoryDeliveryPositionsByDriverIdAndDateAPI() {
return axios
.post("/web-api/reports/history-delivery-position/generate", {
driver_id: this.driver,
initial_date: this.initialDate,
final_date: this.finalDate
})
.then(({ data }) => {
return data;
})
.catch(function() {
alert("Erro ao filtrar relatórios");
});
}
3) Call it like:
this.getHistoryDeliveryPositionsByDriverIdAndDateAPI().then(data => {
this.elementsReport = data;
});

Related

How to display image from MySQL in ReactJS using Express

I have uploaded an image in the images folder of my Node server and the path is stored in the MYSQL database. I want to display the image in my ReactJS application. I am getting the error:
http://127.0.0.1:8080/images/abc.jpg 404 (Not Found)
const baseURL = "http://localhost:8080/data";
export default function Displaydata() {
const [userdata, setuserdata] = React.useState([]);
React.useEffect(() => {
axios.get(baseURL)
.then((response) => {
setuserdata(response.data);
console.log(response.data);
});
}, []);
if (!userdata) return null;
return (
<>
<h2>Data</h2>
<table border="1">
<thead>
<tr>
<th>S.No</th>
<th>userid</th>
<th>Name</th>
</tr>
</thead>
<tbody>
{userdata.map(({ userid, name,image },index) => {
let sno=0;
return (
<tr key={userid}>
<td>{index + 1}</td>
<td>{userid}</td>
<td>{name}</td>
<td><img src={image} alt={image}/></td>
</tr>
);
})}
</tbody>
</table>
</>
);
}
What can I try to fix this?

Unable to fetch object for ngFor in angular component

I am trying to show data in table using ngFor but it is unable to fetch the object that contains data in it. I called 2 services in my ngOnInit method and merged their data together using promises but i am unable to fetch that object in ngFor in my html file
html file
<table class="table table-hover table-striped">
<thead>
<tr>
<th>Date/Time</th>
<th>Course</th>
<th>Location</th>
<th>Instructor</th>
<th>Enrolled</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let obj of completeData">
<td class="trim">{{obj.date}}</td>
<td class="trim">{{obj.course}}</td>
<td class="trim">{{obj.location}}</td>
<td class="trim">{{obj.instructor}}</td>
<td class="trim">Yes</td>
<td class="trim">
<nb-select>
<nb-option value="2">Edit</nb-option>
<nb-option value="3">Delete</nb-option>
<nb-option value="4">View</nb-option>
</nb-select>
</td>
</tr>
</tbody>
</table>
component.ts file
export class UpcomingClassesComponent implements OnInit {
times: ClassTimes = new ClassTimes();
schedule: ClassSchedule = new ClassSchedule();
classes: any;
timing: any;
data: any;
completeData: any;
constructor(private router:Router,
private _classService: ClassServiceProxy) {
}
ngOnInit() {
let dataPromise = new Promise((resolve) => {
this._classService.GetClassData()
.subscribe((result: any) => {
resolve(result[0]);
})
});
let timesPromise = new Promise((resolve) => {
this._classService.GetClassTimes()
.subscribe((result: any) => {
resolve(result[0]);
})
});
Promise.all([dataPromise, timesPromise])
.then((values) => {
//console.log(values);
//let completeData = { ...values[0], ...values[1]};
this.completeData = Object.assign({}, values[0], values[1]);
//console.log(this.completeData);
//console.log("final results : ", completeData);
});
}
}
You might need to force change detection. Try the below code. NgZone
constructor(private zone: NgZone) {
//...
});
this.zone.run(() => {
this.completeData = Object.assign({}, values[0], values[1]);
});

Displaying multiple jsons in VUE

So this is my code
<script>
export default {
name: "app",
data() {
return {
items: []
};
},
created: function() {
this.makeAjaxCall("books.json", "get").then(res => {
this.items = res
return res
}),
this.makeAjaxCall("authors.json", "get").then(resA => {
this.items = resA
return resA
})
},
methods: {
makeAjaxCall:function(url, methodType){
var promiseObj = new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest();
xhr.open(methodType, url, true);
xhr.send();
xhr.onreadystatechange = function(){
if (xhr.readyState === 4){
if (xhr.status === 200){
//alert("xhr done ok");
var response = xhr.responseText;
var respJson = JSON.parse(response);
resolve(respJson);
} else {
reject(xhr.status);
//alert("xhr failed");
}
} else {
//alert("xhr processing");
}
}
//alert("request sent succesfully");
});
return promiseObj;
}
}
};
</script>
<template>
<div id="app">
<table class="booksTable">
<thead>
<tr>
<th>Title</th>
<th>Author</th>
<th>Genre</th>
<th>Image</th>
<th>Availability</th>
<th>Options</th>
</tr>
</thead>
<tbody>
<tr v-for="item in items.books" :key="item.name">
<td>{{item.name}}</td>
<td>{{item.author}}</td>
<td>{{item.genre}}</td>
<td><img id="imageBook" :src="item.imageUrl"></td>
</tr>
</tbody>
</table>
</div>
</template>
I have the function makeAjaxCall that brings me the books.json, but I want to use it for multiple jsons.
I tried to call it under created, with a different json, authors.json, but it doesn't work.
I guess the syntax is wrong.
I know the function could have been created better, but I would like to keep its initial form or maybe add a parameter to be the json file.(Tried that, but didn't work for me)
Any ideas, pretty please?
To bind the data you have to declare first items: {books:[],authors:[]}
Also you are overwriting this.items use this.items.books and this.items.authors to assign.
Below is the example which works without ajax
new Vue ({
el: "#app",
data() {
return {
items: {books:[],authors:[]}
};
},
created: function() {
this.items.books = this.makeAjaxCall("books", "get");
this.items.authors = this.makeAjaxCall("authors", "get");
},
methods: {
makeAjaxCall:function(url, methodType){
if(url == 'books'){
promiseObj= [{name:'name11',author:'author11',genre:'genre11'},{name:'name12',author:'author12',genre:'genre12'}]
}else{
promiseObj= [{name:'name22',author:'author22',genre:'genre22'}]
}
return promiseObj;
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.21/vue.js"></script>
<div id="app">
<table class="booksTable">
<thead>
<tr>
<th>Title</th>
<th>Author</th>
<th>Genre</th>
<th>Image</th>
</tr>
</thead>
<tbody>
<tr v-for="item in items.books" :key="item.name">
<td>{{item.name}}</td>
<td>{{item.author}}</td>
<td>{{item.genre}}</td>
<td><img :src="item.imageUrl"></td>
</tr>
</tbody>
</table>
<table class="authorsTable">
<thead>
<tr>
<th>Title</th>
<th>Author</th>
<th>Genre</th>
<th>Image</th>
</tr>
</thead>
<tbody>
<tr v-for="item in items.authors" :key="item.name">
<td>{{item.name}}</td>
<td>{{item.author}}</td>
<td>{{item.genre}}</td>
<td><img :src="item.imageUrl"></td>
</tr>
</tbody>
</table>
</div>
So I found the answer, after millions of tries and it's pretty simple.
<script>
import './styling.scss'
export default {
name: "app",
data() {
return {
items: {books:[], authors:[]}
};
},
created: function() {
this.makeAjaxCall("books.json", "get").then(res => {
this.items.books = res.books;
return res;
}),
this.makeAjaxCall("authors.json", "get").then(res => {
this.items.authors = res.authors;
return res;
})
},
methods: {
makeAjaxCall:function(url, methodType){
var promiseObj = new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest();
xhr.open(methodType, url, true);
xhr.send();
xhr.onreadystatechange = function(){
if (xhr.readyState === 4){
if (xhr.status === 200){
//alert("xhr done ok");
var response = xhr.responseText;
var respJson = JSON.parse(response);
resolve(respJson);
} else {
reject(xhr.status);
//alert("xhr failed");
}
} else {
//alert("xhr processing");
}
}
//alert("request sent succesfully");
});
return promiseObj;
}
}
};
</script>
<template>
<div id="app">
<table class="booksTable">
<thead>
<tr>
<th>Title</th>
<th>Author</th>
<th>Genre</th>
<th>Image</th>
<th>Availability</th>
<th>Options</th>
</tr>
</thead>
<tbody>
<tr v-for="item in items.books" :key="item.name">
<td>{{item.name}}</td>
<td>{{item.author}}</td>
<td>{{item.genre}}</td>
<td><img id="imageBook" :src="item.imageUrl"></td>
<td>
<button class="btn add"> Add</button>
<button class="btn edit"> Edit</button>
<button class="btn delete"> Delete</button>
</td>
</tr>
</tbody>
</table>
</div>
</template>

Can't iterate React component to create table. Unexpected token

I'm trying to create a table filled by a REST API using ReactJS. The problem is I don't know what I'm doing wrong with the sintax... I'm using ES6.
This is the FooTable:
import React from 'react'
import Foo from './Foo'
export default class FooTable extends React.Component {
render() {
return(
<tr>
<td>id</td>
<td>name</td>
<td>surname</td>
</tr>
{ //<-- This is the marked error by webpack
this.props. Foos.map( foo=>{
return < Foo key={foo.id} name={foo.name} surname={foo.surname}/>
})
}
)
}//end-render
}
This is the Foo class:
import React from 'react'
export default class Foo extends React.Component {
render() {
return <tr>
<td>{foo.name}</td>
<td>{foo.surname}</td>
</tr>
}
}
This is the main render:
render(){
if (this.state.foos.length > 0) {
console.log('Foos size ' + this.state.foos.length);
return <table>
<tbody>
<FooTable foos={this.state.foos}/>
</tbody>
</table>
} else {
return <p className="text-center">Loading Foos...</p>
}
}
Webpack marks an error in FooTable (Unexpected Token). It's marked by a comment.
you need to return single node from your component's (FooTable in this case )render method.
render() {
return(
<tr>
<td>id</td>
<td>name</td>
<td>surname</td>
</tr>
{ //<-- This breaks the single root
this.props.Foos.map( foo=>{
return < Foo key={foo.id} name={foo.name} surname={foo.surname}/>
})
}
)
}
you need to do sth like this :
render() {
return (
<tbody>
<tr>
<td>id</td>
<td>name</td>
<td>surname</td>
</tr>
{this.props.Foos.map(foo => (<Foo key={foo.id} name={foo.name} surname={foo.surname}/>))}
</tbody>)
}
The documentation says (see here) :
Note:
One limitation: React components can only render a single root
node. If you want to return multiple nodes they must be wrapped in a
single root.
You need to wrap your <tr> and your <Foo>elements in a single node, for example a <div>:
render() {
return(
<div>
<tr>
<td>id</td>
<td>name</td>
<td>surname</td>
</tr>
{ //<-- No more multiple roots
this.props.Foos.map( foo => {
return < Foo key={foo.id} name={foo.name} surname={foo.surname}/>
}
</div>
)
}
Hope this helps

using ng-repeat to display data in json file

I am new to angularjs. I want to display the data in the following json file using ng-repeat.
http://www.cricbuzz.com/api/match/current
But I'm confused as there is a number in the data as key to each object. Can someone help me?
THis is a basic way to do it
Partial
<div ng-controller="Ctrl" >
<table>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in rows">
<td>#{{ row.id}}</td>
<td>{{ row.series.name | uppercase }}</td>
</tr>
</tbody>
</table>
</div>
Controller
angular.module('app').controller('Ctrl', ['$scope', 'Resource', function ($scope, Resource) {
var pageChanged = function () {
$scope.myPromise = Resource.get({}, function (response) {
$scope.rows = response;
});
};
pageChanged();
}])
.factory('Resource', ['$resource', function($resource) {
return $resource('http://www.cricbuzz.com/api/match/current', {
}, {
'get': {
method: 'GET',
headers: {"Content-Type": "application/json"}
}
});
}]);