How to add condition if object empty on the vue.js 2? - object

My vue component is like this :
<template>
<div>
<div v-if="!list">No results.</div>
<div v-else class="panel-group" v-for="item in list">
...
</div>
</div>
</template>
<script>
export default {
...
computed: {
list: function() {
return this.$store.state.order.list
}
}
}
</script>
The result of console.log(this.$store.state.order.list) is like this :
Seems it's a object
I try like that, but when the object empty, it not display <div v-if="!list">No results.</div>
Is there anyone who can help me?
Update :
If no data, the result of console.log(this.$store.state.order.list) is like this :

<div v-if="Object.keys(list).length === 0">No results.</div>

Related

Why is this react component not displaying content loaded?

I'm working on this project and I want to display the content I got from the backend routes via axios to Showcase component. But the code doesn't give the output as expected the updated state console.log(cont) is working and no issue but it doesn't rendering contents.The app.js state is received by the component. I want to display the names. The child functional component as follows.
import React from 'react';
import {
Table,
Button
} from 'reactstrap';
function Showcase(props) {
const title = props.title;
const contents = props.contents;
let items_body = [];
items_body = contents.map(cont => {
console.log(cont)
if(cont.category === 'Men') {
return (
<div className="item_card" key={cont._id}>
<div className="itemC_right">
<div className="itemCR_topA">
<div className="itemCR_topA_title">{cont.name}</div>
</div>
</div>
</div>
)
}
else if(cont.category === 'Women') {
return (
<div className="lead content d-flex d-flex justify-content-center mb-3" key={cont.id}>
<div>Name : {cont.name}</div>
</div>
)
}
else if(cont.category === 'Kids') {
return (
<div className="lead content d-flex d-flex justify-content-center mb-3" key={cont.id}>
<div>Name : {cont.name}</div>
</div>
)
}
else
return (
null
)
})
return (
<div id="showcase">
<div id="showcase_card">
<div className="row">
<div className="col-sm-6 d-flex flex-row mt-1">
<h1 className="display-3 txt_secondary text-left" id="showcase_title">{title}</h1>
</div>
<div className="col-sm-6 d-flex flex-row-reverse mt-4">
<small className="txt_secondary text-right">Oreo is a online shopping store made just for you.</small>
</div>
</div>
<div>
{items_body}
</div>
</div>
</div>
)
}
export default Showcase;
The App.js class component
class App extends React.Component {
state = {
title: 'Oreo',
contents: []
}
changeState = (category,data) => {
this.setState({
title: category,
contents: data
})
}
handleNavigation = (e) => {
const option = e.target.innerHTML;
switch(option) {
case "Men":
axios.get('/api/items/men/2')
.then(res => {
this.changeState('Men',res.data);
// console.log(res.data)
})
break;
}
}
render() {
return (
<div>
<NavigationBar handleNavigation={this.handleNavigation} />
<Showcase title={this.state.title} contents={this.state.contents} />
<ItemWindow />
<BottomBar />
</div>
);
}
}
export default App;
In NavigationComponent.js when clicked on Men I'm sending it to App.js then it handles the click event. Why doesn't Showcase.js cannot show/render results? Help.
So I got rid of the if statements under the Showcase.js and could get my results. It seems that I was checking the category twice(in handleNavigation and here). I also added async and await as tonkalata's way.

TypeError: this.props.delItemRow is not a function for deleting item

I have put in my whole day tried every method but to vain my efforts. I am learning React how to make work a delete functionality but then to vain .
A simple TO-DO list where the delete is not working. I dont know where i'm doing wrong.
Here are the js files: display and addList, which is parent to display. Using props the parent function is not being called.
display.js
class DisplayList extends Component{
delRow(en){
this.props.delItemRow(en);
}
render(){
return(
// console.log("check"+this.props.list),
<div>
<h4>DisplayList</h4>
<ul>
{this.props.list.map((item)=>(<li key={item}>{item} <button onClick={this.delRow.bind(this,item)}>D</button> </li>))}
</ul>
</div>
);} }
export default DisplayList;
addlist.js
class AdList extends Component{
constructor(props){
super(props);
this.state={value:'',disArrList:[]}
this.handleChange=this.handleChange.bind(this);
this.handleSubmit=this.handleSubmit.bind(this);
this.delItemRow=this.delItemRow.bind(this);
this.updateItemRow=this.updateItemRow.bind(this);
}
delItemRow(itemName)
{this.setState({disArrList:this.state.disArrList.filter(e1=>e1!==itemName)};
}
handleChange(e){
this.setState({value:e.target.value});
}
handleSubmit(e){
e.preventDefault();
//alert("submit"+this.state.value);
let mycolletion=this.state.disArrList.concat(this.state.value);
this.setState({disArrList:mycolletion});
}
render(){
return(
<div>
<div className="Todo">
<form onSubmit={this.handleSubmit}>
<input type="text" value={this.state.value} onChange={this.handleChange}/>
<input type="submit" value="Add" />
</form>
</div>
<div>
<DisplayList list={this.state.disArrList} removeItem={this.delItemRow} updateItem={this.updateItemRow}/>
</div>
</div>
);}}
export default AdList;
Thank you any help would be appreciated
The prop you are passing is called removeItem, so you have to change it in your snippet.
display.js
delRow(en){
this.props.removeItem(en);
}
render(){
return(
<div>
<ul>
{this.props.list.map((item)=>(<li key={item}>{item} <button onClick={this.delRow.bind(this,item)}>D</button> </li>))}
</ul>
</div>
);
}
In addlist.js you pass this.delItemRow in props as removeItem,
so in display.js you can access to delItem with this.props.removeItem
if you want to access it, with this.props.delItem in display.js simply you can change it into:
<DisplayList list={this.state.disArrList} delItemRow={this.delItemRow} updateItem={this.updateItemRow}/>

Vue.js - Working with Components

I am new to Vue.js. Very new so this question might sound a lot like a first graders. Forgive me.
I have the App.vue and Character.vue setup. I wanted to create characters on the fly and add them to an array (in App.vue) and let the rendering of the look/feel of the characters be done using Character.vue. The characters are created and added to the array and can be retrieved properly. Only thing is...Character.vue doesn't render them properly because for some reason, the character it retrieves from the array is undefined.
Help me?
Attaching files
App.vue
<template>
<div>
<div class='gameHeader'>
<h1>{{ gameHeader }}</h1>
</div>
<div class='gameMessages'>
<div class='gameMessage' v-for="msg in gameMessages">
{{ msg }}
</div>
</div>
<div class='gameMain'>
<button #click="rollNewCharacter">Roll New</button>
<div class="playerParty">
<character v-for="p in playerParty"></character>
</div>
<div class="computerParty">
<character v-for="c in computerParty"></character>
</div>
</div>
<div class='gameFooter'>
{{ gameFooter }}
</div>
</div>
</template>
<script>
import Character from "./assets/components/Character.vue";
export default {
components: { 'character': Character },
data: function(){ return { gameHeader: 'Monster Attack', gameMessages:[], playerParty: [], computerParty: [], gameFooter: '' }; },
methods: {
rollNewCharacter() {
var c = Character;
c.name = 'Usman';
c.type = 'Warrior';
c.mana = 100;
c.health = 100;
c.totalHealth = 100;
c.totalMana = 100;
console.log(c.name);
this.playerParty.push(c);
console.log(this.playerParty[0].name);
//this.computerParty.push(chr2);
}
}
}
</script>
Character.vue
<template>
<div class="character">
<span class='name'>{{ name }}</span><span class='type'>({{ type }})</span>
<div class='health'><div class='total' :class="totalHealth"><div class='health' :class="health"></div></div></div>
<div class='mana'><div class='total' :class="totalMana"><div class='mana' :class="mana"></div></div></div>
<span class='damage'>{{ damage }}</span>
<div class="actions">
<button #click="attack">Attack</button>
<button #click="specialAttack">Special Attack</button>
<button #click="heal">Heal</button>
</div>
</div>
</template>
<script>
export default {
props: [ 'name', 'type', 'mana', 'health', 'damage' , 'totalHealth', 'totalMana' ],
methods: {
attack: function(){},
specialAttack: function(){},
heal: function(){ alert(this.name); console.log(this);}
}
}
</script>
<style>
</style>
You should pass a prop when using the character component:
<character :character="p" v-for="p in playerParty"></character>
I have updated the character to receive only one prop:
export default {
props: [ 'character' ],
methods: {
attack: function(){},
specialAttack: function(){},
heal: function(){ alert(this.name); console.log(this);}
}
}
And this is the character component template with the new prop:
<template>
<div class="character">
<span class='name'>{{ character.name }}</span><span class='type'>({{ character.type }})</span>
<div class='health'><div class='total' :class="character.totalHealth"><div class='health' :class="character.health"></div></div></div>
<div class='mana'><div class='total' :class="character.totalMana"><div class='mana' :class="character.mana"></div></div></div>
<span class='damage'>{{ character.damage }}</span>
<div class="actions">
<button #click="attack">Attack</button>
<button #click="specialAttack">Special Attack</button>
<button #click="heal">Heal</button>
</div>
</div>
</template>

How to replace Aurelia components?

I'm newbie with Aurelia and frontend frameworks generally.
I have page with List
list.html
<template>
<require from="services/list-item"></require>
<div class="container-fluid">
<div class="row row-centered container-top-space">
<div repeat.for="item of items">
<list-item item.bind="item"></list-item>
</div>
</div>
</div>
</template>
list.js
import { inject } from 'aurelia-framework';
import { HttpClient, json } from 'aurelia-fetch-client';
#inject(HttpClient)
export class ListItem{
constructor(httpClient) {
this.items= [];
httpClient.configure(...);
}
}
and ListItem
list-item.html
<template>
<div class="row">
<div class="list-item">
<div class="form-control-inline" style="width:33%">
<span>${item.name}  </span>
</div>
<div class="form-control-inline" style="width:54%">
<span>${item.value}</span>
</div>
<div class="pull-right" style="width:100px">
<button class="btn btn-list-item" type="submit" name="submit" click.delegate="edit($event.target.parentElement)">Edit</button>
</div>
</div>
</div>
</template>
list-item.js
import { bindable } from 'aurelia-framework';
export class ListItem{
#bindable item;
edit(element){
//I'd like to replace view component with update component here
}
}
I'd like to change template of list-item on list-item-edit when edit function will be called, but completely don't know how to make it.

How to dynamically change view in angularjs using ui-router

I have a named view called myView in which I have two div elements that I want to show conditionally using ng-show based on whether the value of $scope.states['currentState'] is 'A' or 'B'. The value of $scope.states['currentState'] is changed when an anchor tag is clicked which calls the doStuff function on the myController controller.
The issue I am having is when the anchor tag is clicked and the doStuff function is clicked, it shows on the console that the value of $scope.states['currentState'] has been modified, but its not updating the myView named view accordingly.
Following is the code for app.js, myView.html and index.html files. The index.html file is being used as a <div ui-view></div> in an index.ejs file that I am rendering using Express with Node.js.
app.js
var app = angular.module("app", ['ui.router']).
config(['$stateProvider', '$urlRouterProvider', '$locationProvider', function($stateProvider, $urlRouterProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
views: {
'': { templateUrl: 'partials/index.html' },
'myView#home': {
templateUrl: 'partials/myView.html',
controller: 'myController'
},
'myOtherView#home': {
templateUrl: 'partials/myOtherView.html',
controller: 'myController'
}
}
});
}])
app.controller("myController", ['$scope', function($scope){
var states = ['A', 'B'];
$scope.states = states;
$scope.states['currentState'] = states['currentState'] || 'A';
$scope.doStuff = function(toState) {
//doing stuff
$scope.states['currentState'] = toState;
console.log($scope.states['currentState']);
};
} ]);
index.html
<div class="main">
<div class="container">
<div class="row margin-bottom-40">
<div class="col-md-12 col-sm-12">
<div class="content-page">
<div class="row">
<div ui-view="myView"></div>
<div ui-view="myOtherView"></div>
</div>
</div>
</div>
</div>
</div>
</div>
myView.html
<div ng-controller='myController'>
<div ng-show="states['currentState'] == 'A'">
//displaying this div if the currentState is A
<a ng-click="doStuff('B')">Do stuff and show B</a>
</div>
<div ng-show="states['currentState'] == 'B'">
//displaying this div if the currentState is B
</div>
</div>
Could somebody help me understand that why am not getting the div with states['currentState'] == 'B' shown, even when I see the value of console.log($scope.states['currentState']) changed from 'A' to 'B' when the doStuff function is called in myController?
Edit:
Here is the demo of the issue I am facing.
Okay So I was mistaken in my comment.
The real issue was that you used {{}} in your ng-show which is not needed as these expect to take angular expressions.Also I would make current state a property of your scope as at the moment you are trying to make it a property of an array inside your scope.
Hope that helps! Below is the modified code for your view:
<div ng-controller='MainCtrl'>
<div ng-show="currentState === 'A'">
<a ng-click="doStuff('B')">Do stuff and show B</a>
</div>
<div ng-show="currentState === 'B'">
<a ng-click="doStuff('A')">Do stuff and show A</a>
</div>
</div>
EDIT: Working plunker http://plnkr.co/edit/1llQMQEdxIwu65MNoorx?p=preview

Resources