link1781 link1782 link1783 link1784 link1785 link1786 link1787 link1788 link1789 link1790 link1791 link1792 link1793 link1794 link1795 link1796 link1797 link1798 link1799 link1800 link1801 link1802 link1803 link1804 link1805 link1806 link1807 link1808 link1809 link1810 link1811 link1812 link1813 link1814 link1815 link1816 link1817 link1818 link1819 link1820 link1821 link1822 link1823 link1824 link1825 link1826 link1827 link1828 link1829 link1830 link1831 link1832 link1833 link1834 link1835 link1836 link1837 link1838 link1839 link1840 link1841 link1842 link1843 link1844 link1845 link1846 link1847 link1848 link1849 link1850 link1851 link1852 link1853 link1854 link1855 link1856 link1857 link1858 link1859 link1860 link1861 link1862 link1863 link1864 link1865 link1866 link1867 link1868 link1869 link1870 link1871 link1872 link1873 link1874 link1875 link1876 link1877 link1878 link1879 link1880 link1881 link1882 link1883 link1884 link1885 link1886 link1887 link1888 link1889 link1890 link1891 link1892 link1893 link1894 link1895 link1896 link1897 link1898 link1899 link1900 link1901 link1902 link1903 link1904 link1905 link1906 link1907 link1908 link1909 link1910 link1911 link1912 link1913 link1914 link1915 link1916 link1917

[Vue.js] Can't access dynamic nested JSON property

Im creating a component to display a table based on JSON data, but nothing is shown for my column when the column’s property key is lieu.ville. How do I fix this?


<ul class=”list-group”>
<li class=”list-group-item list-group-item-info”>
<div class=”row”>
<div v-for=”col in colss” class=”” :class=”bootstrapClass”>{col | capitalize}</div>

<li v-for=”(item,index ) in datas” class=”list-group-item” :key=”item[‘id’]“>
<div class=”row”>
<div v-for=”(value,i) in columns” class=”” :class=”bootstrapClass”>
<i>{ item[value] }</i>


var csrf_token = $(‘meta[name=”csrf-token”]‘).attr(‘content’);

export default {
props: [‘colss’,’columns’,’datas’,’urlajax’],

computed: {
bootstrapClass: function() {
return ‘col-sm-‘ + (12 / this.colss.length );

mounted: function () {

filters: {
capitalize: function (str) {
return str.charAt(0).toUpperCase() + str.slice(1)

vue.js bootstrap:

var listSessions = new Vue({
el: ‘#listmodalSessions’,
data: {
// collection des proprits
columns: [‘id’, ‘ref_session’, ‘datesPeriodesConcat’,’lieu.ville’],
// collection d’affichage
colss: [‘Id’, ‘Ref Session’, ‘Dates’,’Ville’],
datas: [],
urlPrefix:’/admin/User/‘ ,
methods: {
showModal () {

hideModal () {
// id Item reprsente l’id du user auquel appartiennent les permissions de la liste

var MonThis = this;
MonThis.datas = [];

url: this.urlajax,
cache: false,
dataType: ‘json’,
success: function (data, textStatus, jqXHR) {
if (jqXHR.status === 200) {
MonThis.datas = data;
var index = 0;

components: {modalTable},

Sample data:

“id”: 6735,
“formation_id”: 8376,
“statut_session_id”: 1,
“lieu_id”: 1,
“ref_session”: “1 333 7020 19S 10 41 01”,
“prixSession”: 1385,
“intraInter”: 1,
“intraInSitu”: 0,
“commentaires”: null,
“created_at”: “2019-03-25 17:31:29”,
“updated_at”: “2019-03-25 17:31:29”,
“deleted_at”: null,
“periodes”: [{
“id”: 5634,
“session_id”: 6735,
“salle_id”: 43,
“date_debut”: “2019-10-07”,
“date_fin”: “2019-10-11”,
“commentaires”: null,
“created_at”: “2019-03-25 17:31:29”,
“updated_at”: “2019-03-25 17:31:29”,
“deleted_at”: null
“lieu”: {
“id”: 1,
“ville”: “Paris”,
“cp”: “75”,
“region”: null,
“displaySite”: 1,
“created_at”: “2019-03-13 13:24:36”,
“updated_at”: “2019-03-13 13:24:36”
“datesPeriodesConcat”: “2019-10-07 au 2019-10-11”,
“lieu2Display”: “Paris”,
“link”: “<a class=\“btn btn-info\“ href=\“\/session\/6735\“>Session<\/a>”

Solution :

The problem…

item[‘lieu.ville’] is not the same as item.lieu.ville. The former looks up a property named lieu.ville in item, which doesn’t exist in this case. The latter looks up lieu in item, then ville in the result.

One way to solve this is to programmatically split the given object key by . so that the correct property can be resolved:

methods: {
getValue(item, key) {
return key.split(‘.’).reduce((obj,k) => obj[k] || {}, item)

/** The one-liner above is equivalent to the following **/

const keys = key.split(‘.’)
for (const k of keys) {
if (!item) break
item = item[k]
return item || {}

Suboptimal usage…

You could use that getValue method in the template like this:

<li v-for=”item in datas”>
<div class=”row”>
<div v-for=”key in columns”>
<i>{ getValue(item, key) }</i>

But using such methods in the template is inefficient because the method is called on every render, producing the same result each time.

Something better…

You could use a computed property instead, which gets cached to avoid unnecessary recalculations on render. The computed prop (e.g., named tableData) would contain new table data that has its column’s items already resolved:

computed: {
tableData() {
return => ({
columns: => this.getValue(item, key))

Then, you could use the tableData prop in the template like this:

<li v-for=”item in tableData”>
<div class=”row”>
<div v-for=”value in item.columns”>
<i>{ value }</i>