I want to loop through a 2 dimensional array with Vue.js, but when I use a nested v-for inside another v-for, I get this error:
invalid v-for alias "case" in expression: v-for="case in line"
new Vue({
el: "#app",
data: {
chessboard: [
[null,null,null,null],
[null,null,null,null],
[null,null,null,null],
[null,null,null,null]
]
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div class="chessboard">
<div v-for="line in chessboard">
<div v-for="case in line">
<button></button>
</div>
</div>
</div>
</div>
How should I do to make it work?
Thank you for your help.
case is a reserved word :)
(switch-case)
https://jsfiddle.net/3k8dghvo/
<div id="app">
<div class="chessboard">
<div v-for="line in chessboard">
<div v-for="cell in line">
<button></button>
</div>
</div>
</div>
</div>
Related
My function renderTitles is supposed to output many bootstrap cards with title from an array that i got from an API. I have tested before and the array is there and all its data. The problem is when i call renderTitles function it does not output anything.
I have tried many map function examples and none have worked
renderTitles = () => {
return this.state.popularMovies.map(t => {
return (
<div class="container">
<div class="card" style={{ width: "12rem" }}>
<div class="card-body">
<img
class="card-img-top"
src="http://image.tmdb.org/t/p/w342/iflq7ZJfso6WC7gk9l1tD3unWK.jpg"
/>
<h5 class="card-title">t.title</h5>
</div>
</div>
</div>
);
});
};
It is expected to output all titles inside bootstrap cards with one title each.
Try wrapping the data that you want to print in {} for example:
<h5 class="card-title">
{t.title}
</h5>
Also: when you call your renderTitles function, make sure that is wrapped in {} as well:
<div class="all-my-titles">
{this.renderTitles()}
</div>
Try this if it helps
renderTitles = () =>{
return this.state.popularMovies.map((t)=>(
<div class="container">
<div class="card" style={{width: '12rem'}}>
<div class="card-body">
<img class="card-img-top" src="http://image.tmdb.org/t/p/w342/iflq7ZJfso6WC7gk9l1tD3unWK.jpg"/>
<h5 class="card-title">
{t.title}
</h5>
</div>
</div>
</div>
))
}
You need to use wrap both output of renderTitles and t.title in {}.
Reference
I'm pretty new to react and I had a question. I have some code that populates some tabs with some info and I wanted some help creating a function that can be reused multiple times instead of reusing the same code for each tab.
<div className="box box-default">
<div className="box-header with-border">
<h3 className="box-title">Strings Info</h3>
<div className="key-details">
<dl className="dl-horizontal">
<dt>Count</dt>
<dd>{count}</dd>
<dt>Average Length</dt>
<dd>{avg_length}</dd>
</dl>
</div>
</div>
<div className="box-header with-border">
<h3 className="box-title">Strings</h3>
<div>
<pre>
{this.props.raw_strings}
</pre>
</div>
</div>
</div>
I was thinking I could create a populateTabs function that can take the count, average length, and the raw string data from the props as a parameter. The count, avg_length, and raw_strings are different for each tab as they each represent a different string type so I've been reusing this block for every tab despite only changing the 3 variables. What is the best way to cut down on the code reuse in this situation? thanks!
The code can be extracted to a component. In case some parameters are common in some cases, it can be higher-order component that accepts common parameters:
const boxHOC = (count, avg_length) => props => (
<div className="box box-default">
<div className="box-header with-border">
<h3 className="box-title">Strings Info</h3>
<div className="key-details">
<dl className="dl-horizontal">
<dt>Count</dt>
<dd>{count}</dd>
<dt>Average Length</dt>
<dd>{avg_length}</dd>
</dl>
</div>
</div>
<div className="box-header with-border">
<h3 className="box-title">Strings</h3>
<div>
<pre>
{props.raw_strings}
</pre>
</div>
</div>
</div>
);
const OneTwoBox = boxHOC(1, 2);
const ThreeFourBox = boxHOC(3, 4);
React is all about components, so rather than a normal function, you're better off extracting the common markup into a component, which can actually be a "function component" (as opposed to a "class component").
export function PopulateTab({ avgLength, count, rawStrings }) {
return (<div className="box box-default">
<div className="box-header with-border">
<h3 className="box-title">Strings Info</h3>
<div className="key-details">
<dl className="dl-horizontal">
<dt>Count</dt>
<dd>{count}</dd>
<dt>Average Length</dt>
<dd>{avgLength}</dd>
</dl>
</div>
</div>
<div className="box-header with-border">
<h3 className="box-title">Strings</h3>
<div>
<pre>
{rawStrings}
</pre>
</div>
</div>
</div>);
}
if tabsContents is an array of objects like..
const tabsContents = [
{ avgLength: 5, count: 8, rawStrings: "foo" },
{ avgLength: 6, count: 12, rawStrings: "bar" },
];
you can use PopulateTab like so..
import { PopulateTab } from "./populate-tab";
function Tabs({ tabsContents }) {
return (
<div>
{tabsContents.map(
({ avgLength, count, rawStrings }) =>
<PopulateTab avgLength={avgLength} count={count} rawStrings={rawStrings} />
)}
</div>
);
}
or, more concisely..
function Tabs({ tabsContents }) {
return (<div>{tabsContents.map(props => <PopulateTab {...props} />)}</div>);
}
I need to make following functionality using angularJS without using id for controls
here is HTML code::
<div id="outterSpliter">
<div id="innerSpliter">
<div>
<div class="cont">Pane 1 </div>
</div>
<div>
<div class="cont">Pane 2 </div>
</div>
</div>
<div>
<div class="cont">Pane 3 </div>
</div>
</div>
here is script
$("#outterSpliter").ejSplitter({
height: 250, width: 401,
orientation: ej.Orientation.Vertical,
properties: [{}, { paneSize: 80 }]
});
$("#innerSpliter").ejSplitter();
To render the Splitter in Angular way, use the directive 'ej-splitter'. All JS component properties support one way biding. You need to add the prefix "e-" to the properties. Refer the below code to render the Splitter in Angular way.
<div ng-controller="SplitCtrl">
<div ej-splitter e-height="250" e-width="401" e-orientation="vertical" e-properties="new">
<div ej-splitter e-width="401">
<div>
<div class="cont">Pane 1 </div>
</div>
<div>
<div class="cont">Pane 2 </div>
</div>
</div>
<div>
<div class="cont">Pane 3 </div>
</div>
</div>
</div>
As you can see in the above code snippet, for the 'e-properties', I have specified the value "new". The "e-properties" of splitter receives array of objects as value. So in the Script section I have assigned the values of Splitter pane properties to a scope variable and assigned it as value for e-properties.
Script code
<script>
angular.module('splitApp', ['ejangular']).controller('SplitCtrl', function ($scope) {
$scope.new = [{}, { paneSize: 80 }];
});
</script>
<style type="text/css" class="cssStyles">
.cont {
padding: 10px 0 0 10px;
}
</style>
Here's the jsFiddle: http://jsfiddle.net/VSph2/274/
I'm trying to make a filter with checkboxes.
When the user clicks the checkbox, it adds the id to an array called color_ids. I know that's working because I print the array in the console.
However, when I try to combine that with a filter, it doesn't work. I try to pass the $scope.color_ids array, but it is always passing an empty array and not passing the array with values in them.
app.controller('IndexCtrl', ['$scope', "Product", "Color", function($scope, Product, Color) {
...
// this method is triggered by a checkbox
$scope.toggleColorFilter = function(color_id) {
var index = $scope.color_ids.indexOf(color_id);
if (index > -1) {
$scope.color_ids.splice(index, 1);
} else {
$scope.color_ids.push(color_id);
}
console.log($scope.color_ids); //<-- prints the array properly with the new values.
};
}]);
and a filter that isn't working:
app.filter('productFilter', function(){
return function(input, color_ids) {
console.log(color_ids); //<-- prints an empty array all the time [ ]
return input;
}
})
This is my HTML
<h2>Products</h2>
<div class="filters col-two" ng-controller="IndexCtrl">
<h3>Color</h3>
<div ng-repeat="color in colors">
{{color.name}} <input type="checkbox" ng-model="color_ids" ng-change="toggleColorFilter(color.id)">
</div>
<h3>Shape</h3>
<h3>Material</h3>
</div>
<div class="products col-ten" ng-controller="IndexCtrl">
<div class="product" ng-repeat="product in products | productFilter:color_ids">
<h3>
{{ product.name }}
</h3>
<div class="product-thumbs">
<div class="image-wrapper" ng-repeat="product_color in product.products_colors">
<img src="{{ product_color.color.image.url }}" width="75" height="40">
</div>
</div>
</div>
</div>
I want the filter to eventually only show products with a color_id that exist in the color_ids array.
You have three divs with ng-controller="IndexCtrl" in your JSFiddle example. This is the problem. Each time the Angular compiler finds ng-controller in the HTML, a new scope is created.
<div class="filters col-two" ng-controller="IndexCtrl">
<h3>Color</h3>
<div ng-repeat="color in colors">{{color.name}}
<input type="checkbox" ng-model="color_ids" ng-change="toggleColorFilter(color.id)">
</div>
</div>
<div class="products col-ten" ng-controller="IndexCtrl">
<div class="product" ng-repeat="product in products | productFilter:color_ids">
{{ product.name }}
</div>
</div>
Simpliest way is to place this code in one controller and it will print 2 similiar arrays in your console:
<div ng-controller="IndexCtrl">
<div class="filters col-two">
<h3>Color</h3>
<div ng-repeat="color in colors">{{color.name}}
<input type="checkbox" ng-model="color_ids" ng-change="toggleColorFilter(color.id)">
</div>
</div>
<div class="products col-ten">
<div class="product" ng-repeat="product in products | productFilter:color_ids">
{{ product.name }}
</div>
</div>
</div>
JSFiddle
The filter is applied before the color_ids is updated, you should apply the filter in the controller inside the toggle function:
$filter('productFilter')($scope.products, $scope.color_ids);
Here is the working findle (at least I think): http://jsfiddle.net/VSph2/276/
Don't forget to inject the $filter in your controller.
I am testing a web application project using Protractor . The few test cases which I have written is running fine but I am getting difficulties when I try to count the number of div elements present inside a parent div element, The structure of my div is given below
<div class="page-kontact-main">
<div class="buttons contact_page">
Om oss
Offert
Våra Tjänster
</div>
<div class="row kontact-title">
<h2>Våra medarbetare</h2>
<p>
Test desc <span class="s47jd228h2" id="s47jd228h2_5">med</span> passion och engagemang för it & system. Skicka in din ansöka
</p>
<p> </p>
</div>
<div class="row clearfix">
<div class="col206"></div>
<div class="col206"></div>
<div class="col206"></div>
<div class="col206"></div>
<div class="col206"> </div>
<div class="col206"></div>
<div class="col206"></div>
<div class="col206"> </div>
</div>
</div>
And I have written the test case like this as given below but it is not running the error is expected undefined to equal 21.
it('Getting the count of contact names ', function() {
driver.get("http://mysite.se/kontakt/");
var element = driver.findElement(protractor.By.css('.clearfix .col206'));
expect(element.length).toEqual(21);
});
Thanks
Utpal
You should use element.all and count() instead of length:
it('Getting the count of contact names ', function() {
driver.get("http://mysite.se/kontakt/");
var elements = element.all(protractor.By.css('.clearfix .col206'));
expect(elements.count()).toEqual(21);
});
$ and $$ are equivalent to element.all and by.css, so you can use the following code
it('Getting the count of contact names ', function() {
driver.get("http://mysite.se/kontakt/");
var elements = $$('.clearfix .col206'));
expect(elements.count()).toEqual(21);
});