vue.js render a list in array of objects - javascript

I have a instance of Vue.js that make a fetch GET request and i want to display all the data using v-for but i can access the field that i want inside the jsonBody requisition.
My instance of vue.js:
var pedidosTable = new Vue({
el: '#pedidosTable',
data: function(){
return{
listOfDi: [],
listOfStep1: []
}
},
created: function(){
const req = fetch("http://localhost:4242/api/v1/dis").then(response =>{
return response.json();
}).then(jsonBody =>{
this.listOfDi = jsonBody;
});
},
methods:{
},
});
my HTML:
<tr v-for="item of listOfDi">
<td>{{ item.DI.Step1[0].nomeDoCliente }}</td>
</tr>
My json in the fetch request:
[
{
"_id":"5f4608e4516d5c137e9d40e7",
"DI":{
"Step1":[
{
"codigoCliente":"56777",
"operacao":"PRÓPRIA",
"tipoDeOperacao":"TRADING",
"lucro":"REAL",
"beneficioIpi":"NÃO",
"consumidor":"P. JURÍDICA",
"rateio":"PESO",
"nomeDoCliente":"Submarino",
"dolarDi":4.4359,
"dolarCambio":4.5
}
],
"Step2":[
{
"id":{
"oid":"5f232394ac7e930548107d16"
},
"produto":"cadeira de rodas",
"ncm":"467.987",
"descricao":"cadeira de rodas teste",
"cliente_id":{
"oid":"5f21e23eac7e9305490f9424"
},
"aliqII":0.2,
"aliqIpi":0,
"aliqPis":0.21,
"aliqCofins":0.0965,
"pesoUnitario":0.43,
"unitario":0.88,
"dumping":0,
"cubagemUnitario":0,
"quantidade":33,
"icmEstadoDestino":0,
"mvaAjustado":0,
"markup":0.12,
"selected":true,
"url":"http://localhost:3000/produtos/5f232394ac7e930548107d16.json"
},
{
"id":{
"oid":"5f232c61ac7e930a6f8ea06a"
},
"produto":"Bicicleta",
"ncm":"456.879",
"descricao":"Bicicleta caloi",
"cliente_id":{
"oid":"5f21e23eac7e9305490f9424"
},
"aliqII":0.2,
"aliqIpi":0,
"aliqPis":0.21,
"aliqCofins":0.0965,
"pesoUnitario":0.43,
"unitario":0.78,
"dumping":0,
"cubagemUnitario":0,
"quantidade":44,
"icmEstadoDestino":0,
"mvaAjustado":0,
"markup":0.12,
"selected":true,
"url":"http://localhost:3000/produtos/5f232c61ac7e930a6f8ea06a.json"
}
],
"Step3":[
{
"freteInternacional":1790.36,
"capatazia":384.35,
"siscomex":260.1,
"marinhaMercante":2076.97,
"outrasDespesasAduaneiras":1000
}
],
"Step4":[
{
"armazenagemZonaPrimaria":2986,
"diferencaFreteInternacional":158.09,
"despachante":1835.68,
"liStep4":53.53,
"taxasBl":844.05,
"tarifaCambial":250,
"multa":0,
"taxaExpediente":250,
"freteAoCliente":1194,
"debitoIcms":0.04,
"pagEfetivo":0.04,
"pagDesembaraco":0.01,
"descontoComercial":0.01,
"debitoPIS":0.0165,
"debitoCofins":0.076,
"IR":0.25,
"CSLL":0.09
}
]
}
},
{
"_id":"5f460d55f46a2b160079f9a8",
"DI":{
"Step1":[
{
"codigoCliente":"98978",
"operacao":"PRÓPRIA",
"tipoDeOperacao":"TRADING",
"lucro":"REAL",
"beneficioIpi":"NÃO",
"consumidor":"P. JURÍDICA",
"rateio":"PESO",
"nomeDoCliente":"Black & Decker",
"dolarDi":4.4359,
"dolarCambio":4.5
}
],
"Step2":[
{
"id":{
"oid":"5f077925ac7e9319ff7d1c6b"
},
"produto":"cafeteira",
"ncm":"9878.7389",
"descricao":"cafeteira capsula",
"cliente_id":{
"oid":"5f0775e8ac7e9319ff7d1c68"
},
"aliqII":0.2,
"aliqIpi":0,
"aliqPis":0.21,
"aliqCofins":0.0965,
"pesoUnitario":0.43,
"unitario":0.78,
"dumping":0,
"cubagemUnitario":0,
"quantidade":12,
"icmEstadoDestino":0,
"mvaAjustado":0,
"markup":0.12,
"selected":true,
"url":"http://localhost:3000/produtos/5f077925ac7e9319ff7d1c6b.json"
}
],
"Step3":[
{
"freteInternacional":1790.36,
"capatazia":384.35,
"siscomex":260.1,
"marinhaMercante":2076.97,
"outrasDespesasAduaneiras":1000
}
],
"Step4":[
{
"armazenagemZonaPrimaria":2986,
"diferencaFreteInternacional":158.09,
"despachante":1835.68,
"liStep4":53.53,
"taxasBl":844.05,
"tarifaCambial":250,
"multa":0,
"taxaExpediente":250,
"freteAoCliente":1194,
"debitoIcms":0.04,
"pagEfetivo":0.04,
"pagDesembaraco":0.01,
"descontoComercial":0.01,
"debitoPIS":0.0165,
"debitoCofins":0.076,
"IR":0.25,
"CSLL":0.09
}
],
}
}
]
How can i acess and display the field nomeDoCliente inside the Step1 array in my v-for list?

Related

Using an if condition inside a V-For Loop in Vue JS

I am having a problem passing an if condition inside a v-for loop in VueJS. I want to see if a value in the text field is greater than 30 to give an alert but I can't figure out how i can call my function inside the loop. Here is my code: I have tried using v-if but still not lucky
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js">
</script>
<tbody>
<tr> v-for="item in marksData">
<td>{{item.studentName}}</td>
<td>{{item.studentRegNo}}</td>
<td><input v-model.number="item.cat1Marks" required="required" /> *...V-if
to check the condition here.... or call any function to check*</td>
<td><button v-on:click.prevent="saveMarks(item)"
type="submit">Save</button></td>
</tr>
</tbody>
var subjectStudentsVM = new Vue({
el: "#subjectStudentsSection",
data: function() {
return {
id: '',
studentRegNo: '',
studentName: '',
marksData: Array(),
}
},
created: function() {
this.getAllSubjects();
},
methods: {
getAllSubjectStudents: function(subject) {
var self = this;
console.log(this.subject.subjectCode)
axios.get("/Marks/students/" +
this.subject.subjectCode).then(function(response) {
this.marksData = response.data;
}.bind(this)).catch(function(error) {
console.log('Error while fetching student data: ' + error)
})
},
computed:{
CheckData(item) {
if (item.cat1Marks > 30 && item.cat1Marks > 0) {
alert("Marks should be less than 30");
}
console.log(mark);
return mark;
}
}
If I understand your question. I think you should check the input first. Then return the alert() if it's necessary.
inside methods
giveAlert(){
alert("Marks should be less than 30");
}
inside computed:
checkInput(val){
if (val > 30 && val > 0) {
this.giveAlert()
} else {//do nothing}
}
Also mentioned in the comments. You should correct the typo of v-for.
the html will not cause a alert it's self so you have to run the checkdata in the created function.
created:function(){
this.getAllSubjects();
for(var i=0;i<this.marksData.length;i++){
var item=this.marksData[i];
if(item.cat1marks>30){
alert("marks should be less than 30");
}
}
}
Computed variable are defined as functions cause they react on changes in the reactive varables of the vue component. But they are not designed to expect any variable passing them directly.
Use subcomponent created hook like this:
<div id="app">
<p v-for="student in marksData">
<mystudent :student="student" />
</p>
</div>
<script>
var app = new Vue({
el: "#app",
data: function() {
return {
marksData: [{
studentName: 'Alan',
studentRegNo: 1,
cat1Marks: 21
},{
studentName: 'Jessica',
studentRegNo:2,
cat1Marks: 31
},{
studentName: 'Joe',
studentRegNo: 3,
cat1Marks: 4
}],
}
},
components: {
Mystudent: {
props: ['student'],
created() {
if (this.student.cat1Marks > 30) alert(`Student ${ this.student.studentName } reached ${ this.student.cat1Marks } mark`)
},
render (h) {
return h('span', `Name: ${ this.student.studentName } RegNo: ${ this.student.studentRegNo } Marcs: ${ this.student.cat1Marks }`)
}
}
}
});
</script>
UPDATED
After the comment i realized that i didn't understood the question
So here is updated code example, where the score check is in method section not in computed and the trigger is the #change event. Notice the #change triggers first when the focus is taken out of the input field.
<div id="app">
<p v-for="(student, i) in marksData">
Student: {{ student.studentName }} Mark: <input v-model="student.cat1Marks" type="text" #change="checkStudent(student)">
</p>
</div>
<script>
var app = new Vue({
el: "#app",
data: function() {
return {
test: 1,
marksData: [{
studentName: 'Alan',
studentRegNo: 1,
cat1Marks: 21
},{
studentName: 'Jessica',
studentRegNo:2,
cat1Marks: 31
},{
studentName: 'Joe',
studentRegNo: 3,
cat1Marks: 4
}],
}
},
methods: {
checkStudent (student) {
if (student.cat1Marks > 30) alert(`Student ${student.studentName } reached ${ student.cat1Marks } mark`)
}
}
});
</script>
For anyone having a similar problem I added this function
up(item){
if (item.cat1Marks > 30) {
item.cat1Marks=0;
alert("Marks cannot be greater than 30")
}else{}
},
//and called this function in my input
<td> <input type="text" name="cat1Marks"
v-model.number="item.cat1Marks" v on:input="up(item)"
required="required" /></td>

Vue.js : How to iterate with v-for into a dynamic array

I want to display multiples html tables of tools (1 table = 1 tool's categorie / 1 tr = 1 tool).
data() {
return {
cats: '',
tools: [],
};
},
methods: {
getToolCats() {
var rez = getToolCats();
rez.then(data => this.receiveCats(data) )
},
receiveCats(_cats){
this.cats = _cats;
_cats.forEach(cat => {
getToolsByCat(cat.href).then(data => this.tools[cat.href] = data);
});
console.log(this.tools);
},
},
mounted() {
this.getToolCats();
},
cats (ie categories) is an array populated with an API call. Then for each cat, an API Call give me a tool list of that cat, that I place into the tools array (this.tools[cat.href] = data).
Here is the display code :
<div v-for="cat in cats" :key="cat.href" class="tbox col-xs-12 col-sm-6">
....
<table class="table table-hover">
<tr v-for="tool in tools[cat.href]" :key="tool.href">
<td>...</td>
</tr>
</table>
....
</div>
If i'm using a single var to store lthe tool list, all is OK. But while I don't know how many cats I'm going to have, I can't create a car for each category.
I think the problem could be there :
Using an array in v-for with a key not defined at mounted state :
v-for="tool in tools[cat.href]
I'll appreciate any help !
Vue can't detect dynamic property addition in this.tools[cat.href] = data, but it would detect the change with this.$set or Vue.set in this.$set(this.tools, cat.href, data):
new Vue({
el: '#app',
data() {
return {
cats: [],
tools: {}, // <-- make this an object (not an array)
};
},
mounted() {
this.getToolCats();
},
methods: {
getToolCats() {
// setTimeout to simulate delayed API calls...
setTimeout(() => {
this.cats = [
{ href: 'https://google.com' },
{ href: 'https://microsoft.com' },
{ href: 'https://apple.com' },
{ href: 'https://amazon.com' },
];
this.cats.forEach((cat, i) => {
setTimeout(() => {
const data = { href: cat.href };
this.$set(this.tools, cat.href, data); // <-- use this.$set for dynamic property addition
}, i * 1000);
})
}, 1000);
}
}
})
<script src="https://unpkg.com/vue#2.5.17"></script>
<div id="app">
<div v-if="!cats || cats.length == 0">Loading...</div>
<div v-for="cat in cats" :key="cat.href" v-else>
<table>
<tr v-for="tool in tools[cat.href]" :key="tool.href">
<td>cat.href: {{cat.href}}</td>
</tr>
</table>
</div>
<pre>tools: {{tools}}</pre>
</div>

Model and Computed Property interaction in Vue.js

Using vue.js I am trying to build a simple task manager.
When a user clicks the "complete" checkbox I want two things to happen:
If the "Show all tasks" is unchecked, hide the task.
Send an ajax request to the server to mark the task as complete/open.
The impotent parts are shown below:
<div id="tasks-app">
<input type="checkbox" id="checkbox" v-model="show_all">
<label for="checkbox">Show all tasks</label><br>
<table class="table">
<tr><th v-for="column in table_columns" v-text="column"></th><tr>
<tr v-for="row in visibleTasks" :class="{danger: !row.daily_task.complete && row.daily_task.delayed, success: row.daily_task.complete}">
<td v-text="row.task.name"></td>
<td v-text="row.task.deadline"></td>
<td v-text="row.daily_task.status"></td>
<td v-text="row.daily_task.task_user"></td>
<td>
<input type="checkbox" v-on:change="updateStatus(row)" v-model="row.daily_task.complete" >Complete</input>
</td>
<td><input v-model="row.daily_task.delay_reason"></input></td>
</table>
</div>
And the VUE.js code:
app = new Vue({
el: '#tasks-app',
data: {
table_columns: ['Task','Deadline','Status','User','Actions','Reason'],
tasks: [],
filter_string: '',
show_all: false
},
computed: {
visibleTasks() {
show_all = this.show_all
if(show_all){
search_filter = this.tasks
}else{
search_filter = _.filter(this.tasks,function(task){
return !task.daily_task.complete;
})
}
return search_filter
}
},
methods: {
updateStatus(row){
var id = row.daily_task.id
var complete = row.daily_task.complete
if(complete){
axios.get('set_task_complete/' + id)
}else{
axios.get('set_task_open/' + id)
}
}
}
})
If the show all checkbox is checked, this works as expected. The data changes and then the updateStatus function is called.
If however the show all checkbox is unchecked, the visibleTasks will trigger and the logic for the updateStatus will fail, as the row will be hidden and the ID that is send to the server will be off by one. If the row hides before updateStatusis called the wrong row is passed to the updateStatus function.
I could solve this by adding a filter update at the end of updateStatus function but that does not seems to utilize the Vue.js library. Could someone help me what components of Vue you would use to solve this problem?
You can simplify a lot if you separate the logic:
Loop over every tasks (completed or not) to display them (without considering show_all)
Update tasks with v-on:click="updateStatus(row)"
On each tr, add v-show="show_all || !row.status.complete"
Your problem is use both change event handle and model. Both actually, trigger at same time when you click on the checkbox.
<input type="checkbox" v-on:change="updateStatus(row)" v-model="row.daily_task.complete" >Complete</input>
You should edit your code use only v-on:change="updateStatus(row)". After updateStatus complete ajax calls toggle row.daily_task.complete to trigger visibleTasks to update your view.
updateStatus(row){
var id = row.daily_task.id
var complete = !row.daily_task.complete
var p;
if(complete){
p = axios.get('set_task_complete/' + id)
}else{
p = axios.get('set_task_open/' + id)
}
p.then(() => row.daily_task.complete = complete)
}
I've refactored your code a bit and it seems to work fine:
you shouldn't use v-on:change, instead, use <input type="checkbox" v-on:click="updateStatus(row)" v-bind:checked="row.daily_task.complete">
Don't update row.daily_task.complete straight away, update it only when the asynchronous axios is complete.
const fakeUpdateComplete = (id) => {
return new Promise((resolve, reject) => { resolve(true); });
};
const fakeUpdateIncomplete = (id) => {
return new Promise((resolve, reject) => { resolve(true); });
};
const app = new Vue({
el: '#tasks-app',
data: {
history: [],
table_columns: ['Task','Deadline','Status','User','Actions','Reason'],
tasks: [
{
task: {
name: 'A',
deadline: '2017-01-01',
},
daily_task: {
id: 1,
status: '',
task_user: '',
complete: true,
delayed: false,
delay_reason: ''
}
},
{
task: {
name: 'B',
deadline: '2017-01-02',
},
daily_task: {
id: 2,
status: '',
task_user: '',
complete: false,
delayed: false,
delay_reason: ''
}
},
{
task: {
name: 'C',
deadline: '2017-01-03',
},
daily_task: {
id: 3,
status: '',
task_user: '',
complete: false,
delayed: false,
delay_reason: ''
}
},
{
task: {
name: 'D',
deadline: '2017-01-03',
},
daily_task: {
id: 4,
status: '',
task_user: '',
complete: true,
delayed: false,
delay_reason: ''
}
},
{
task: {
name: 'E',
deadline: '2017-01-03',
},
daily_task: {
id: 5,
status: '',
task_user: '',
complete: false,
delayed: false,
delay_reason: ''
}
}
],
filter_string: '',
show_all: true
},
computed: {
visibleTasks() {
const show_all = this.show_all
let search_filter;
if(show_all){
search_filter = this.tasks
}else{
console.log(this.tasks);
search_filter = this.tasks.filter(task => {
return !task.daily_task.complete
});
}
return search_filter
}
},
methods: {
updateStatus(row){
const id = row.daily_task.id;
const complete = !row.daily_task.complete;
if (complete) {
fakeUpdateComplete(id).then(() => {
this.history.push(`Task ${row.task.name} with id ${row.daily_task.id} is marked as complete`);
row.daily_task.complete = !row.daily_task.complete;
});
} else {
fakeUpdateIncomplete(id).then(() => {
this.history.push(`Task ${row.task.name} with id ${row.daily_task.id} is marked as incomplete`);
row.daily_task.complete = !row.daily_task.complete;
});
}
/*
if(complete){
axios.get('set_task_complete/' + id)
}else{
axios.get('set_task_open/' + id)
}
*/
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script>
<div id="tasks-app">
<input type="checkbox" id="checkbox" v-model="show_all">
<label for="checkbox">Show all tasks</label><br>
<table class="table">
<tr><th v-for="column in table_columns" v-text="column"></th><tr>
<tr
v-for="row in visibleTasks"
:class="{danger: !row.daily_task.complete && row.daily_task.delayed, success: row.daily_task.complete}"
>
<td>{{row.task.name}}</td>
<td>{{row.task.deadline}}</td>
<td>{{row.daily_task.status}}</td>
<td>{{row.daily_task.task_user}}</td>
<td>
<input type="checkbox" v-on:click="updateStatus(row)" v-bind:checked="row.daily_task.complete">
<label for="complete">Complete</label>
</td>
<td><input v-model="row.daily_task.delay_reason" /></td>
</tr>
</table>
<div>
<div><b>Data:</b></div>
<div>{{this.tasks}}</div>
</div>
<div>
<div><b>History:</b></div>
<div v-for="item in history">
{{item}}
</div>
</div>
</div>

Accessing JSON element which has a number for the name

I have tried to access an element of the json structure but can't. I have tried the following.
I am using the npm package json-query to extract part of the bigger JSON object.
var rslt = jsonQuery('results[**][* status=active]', {
data: response
});
var make = JSON.stringify(rslt.value[0]["parms"]["make"])
Bu this does not work, I have also tried to get the following data from the JSON:
var img = JSON.stringify(rslt.value[0]["photos"]["1"]["320x240"]);
var subtitle = JSON.stringify(rslt.value[0]["parms"]["price"]["1"]) + ' EUR';
This is the JSON data I am working with:
{
"value":[
{
"id":7038271775,
"user_id":1307227,
"status":"active",
"title":"",
"url":"https://www.autovit.ro/anunt/nissan-navara-ID7GjS0w.html",
"created_at":"2017-01-06 17:49:35",
"valid_to":"2017-02-03 17:56:16",
"description":"Data inmatriculare: 02.03.2015.\r\n4x4 \r\nABS \r\nAer conditionat \r\nComputer de bord \r\nGeamuri electrice \r\nInchidere centralizata \r\nJante aliaj \r\nRadio CD \r\nServodirectie \r\nVolan multifunctional",
"category_id":29,
"region_id":46,
"city_id":24691,
"city":{
"ro":"Voluntari",
"en":"Voluntari"
},
"coordinates":{
"latitude":44.49192877,
"longitude":26.12458706,
"radius":0,
"zoom_level":16
},
"advertiser_type":"business",
"contact":{
"person":"LeasePlan Outlet Center",
"phone_numbers":[
"0753312151"
]
},
"params":{
"make":"nissan",
"model":"navara",
"year":2014,
"mileage":16785,
"engine_capacity":2500,
"vin":"VSKCVND40U0566467",
"fuel_type":"diesel",
"gearbox":"manual",
"transmission":"all-wheel-lock",
"particle_filter":"0",
"green_tax":"1",
"damaged":"0",
"body_type":"suv",
"door_count":4,
"color":"white",
"metallic":"0",
"pearl":"0",
"matt":"0",
"rhd":"0",
"features":[ ],
"price":{
"0":"price",
"1":15900,
"currency":"EUR",
"gross_net":"net"
},
"vat":"1",
"financial_option":"1",
"leasing_concession":"0",
"date_registration":"2014-1-01",
"registered":"1",
"original_owner":"1",
"no_accident":"0",
"service_record":"0",
"historical_vehicle":"0",
"tuning":"0"
},
"photos":{
"1":{
"1080x720":"https://img41.autovit.ro/images_autovitro/820558483_1_1080x720.jpg",
"732x488":"https://img40.autovit.ro/images_autovitro/820558483_1_732x488.jpg",
"320x240":"https://img42.autovit.ro/images_autovitro/820558483_1_320x240.jpg",
"148x110":"https://img40.autovit.ro/images_autovitro/820558483_1_148x110.jpg"
},
"2":{
"1080x720":"https://img41.autovit.ro/images_autovitro/820558483_2_1080x720.jpg",
"732x488":"https://img42.autovit.ro/images_autovitro/820558483_2_732x488.jpg",
"320x240":"https://img42.autovit.ro/images_autovitro/820558483_2_320x240.jpg",
"148x110":"https://img42.autovit.ro/images_autovitro/820558483_2_148x110.jpg"
},
"3":{
"1080x720":"https://img42.autovit.ro/images_autovitro/820558483_3_1080x720.jpg",
"732x488":"https://img42.autovit.ro/images_autovitro/820558483_3_732x488.jpg",
"320x240":"https://img40.autovit.ro/images_autovitro/820558483_3_320x240.jpg",
"148x110":"https://img42.autovit.ro/images_autovitro/820558483_3_148x110.jpg"
},
"4":{
"1080x720":"https://img42.autovit.ro/images_autovitro/820558483_4_1080x720.jpg",
"732x488":"https://img40.autovit.ro/images_autovitro/820558483_4_732x488.jpg",
"320x240":"https://img42.autovit.ro/images_autovitro/820558483_4_320x240.jpg",
"148x110":"https://img42.autovit.ro/images_autovitro/820558483_4_148x110.jpg"
},
"5":{
"1080x720":"https://img41.autovit.ro/images_autovitro/820558483_5_1080x720.jpg",
"732x488":"https://img41.autovit.ro/images_autovitro/820558483_5_732x488.jpg",
"320x240":"https://img41.autovit.ro/images_autovitro/820558483_5_320x240.jpg",
"148x110":"https://img40.autovit.ro/images_autovitro/820558483_5_148x110.jpg"
},
"6":{
"1080x720":"https://img40.autovit.ro/images_autovitro/820558483_6_1080x720.jpg",
"732x488":"https://img42.autovit.ro/images_autovitro/820558483_6_732x488.jpg",
"320x240":"https://img40.autovit.ro/images_autovitro/820558483_6_320x240.jpg",
"148x110":"https://img42.autovit.ro/images_autovitro/820558483_6_148x110.jpg"
},
"7":{
"1080x720":"https://img40.autovit.ro/images_autovitro/820558483_7_1080x720.jpg",
"732x488":"https://img41.autovit.ro/images_autovitro/820558483_7_732x488.jpg",
"320x240":"https://img40.autovit.ro/images_autovitro/820558483_7_320x240.jpg",
"148x110":"https://img40.autovit.ro/images_autovitro/820558483_7_148x110.jpg"
},
"8":{
"1080x720":"https://img42.autovit.ro/images_autovitro/820558483_8_1080x720.jpg",
"732x488":"https://img41.autovit.ro/images_autovitro/820558483_8_732x488.jpg",
"320x240":"https://img42.autovit.ro/images_autovitro/820558483_8_320x240.jpg",
"148x110":"https://img40.autovit.ro/images_autovitro/820558483_8_148x110.jpg"
},
"9":{
"1080x720":"https://img41.autovit.ro/images_autovitro/820558483_9_1080x720.jpg",
"732x488":"https://img40.autovit.ro/images_autovitro/820558483_9_732x488.jpg",
"320x240":"https://img40.autovit.ro/images_autovitro/820558483_9_320x240.jpg",
"148x110":"https://img42.autovit.ro/images_autovitro/820558483_9_148x110.jpg"
},
"10":{
"1080x720":"https://img41.autovit.ro/images_autovitro/820558483_10_1080x720.jpg",
"732x488":"https://img42.autovit.ro/images_autovitro/820558483_10_732x488.jpg",
"320x240":"https://img40.autovit.ro/images_autovitro/820558483_10_320x240.jpg",
"148x110":"https://img40.autovit.ro/images_autovitro/820558483_10_148x110.jpg"
},
"11":{
"1080x720":"https://img42.autovit.ro/images_autovitro/820558483_11_1080x720.jpg",
"732x488":"https://img42.autovit.ro/images_autovitro/820558483_11_732x488.jpg",
"320x240":"https://img41.autovit.ro/images_autovitro/820558483_11_320x240.jpg",
"148x110":"https://img42.autovit.ro/images_autovitro/820558483_11_148x110.jpg"
}
},
"image_collection_id":820558483,
"last_update_date":"2017-01-24 18:00:26",
"new_used":"used"
}
],
"is_last_page":false,
"is_first_page":true,
"current_page":1,
"total_pages":33,
"current_elements":1,
"total_elements":33
}
I don't know what excatly "json-query" does but I think you can extract any JSON part safely like this;
function dig(input, key) {
var keys = (""+ key).split("."), key = keys.shift();
if (!keys.length) {
return input[key];
}
return dig(input[key], keys.join("."));
}
// here that gives me already without any error thrown >> https://img42.autovit.ro/images_autovitro/820558483_1_320x240.jpg
var p = dig(rslt, "results.0.photos.1.320x240");
console.log(p);
// this is same with
console.log(rslt.results[0].photos[1]["320x240"]);
Credits: https://github.com/yay-couch/couch-js/blob/master/couch/util/util.js#L46
i'm not sure how its not working, the only problem i see with your code is you mistaken by writing params and you write parms

ng-repeat with JSON object doesn't work

It must be the heat...
I have a json object that I want to run through a ng-repeat, should be simple, but alas! it doesn't work.
HTML
<a data-ng-repeat="x in template.menuObj" href="{{ x.link }}">{{ x.name }}</a>
JSON
[
{
"ACL":{
"*":{
"read":true
}
},
"link":"home",
"menu":"main",
"name":"Home",
"order":1,
"objectId":"aDcb0HUXwB",
"createdAt":"2015-08-05T15:29:05.948Z",
"updatedAt":"2015-08-05T15:29:11.915Z"
},
{
"ACL":{
"*":{
"read":true
}
},
"link":"category/the-interesting-stuff",
"menu":"main",
"name":"The Interesting Stuff",
"order":2,
"objectId":"znXfUF0kdJ",
"createdAt":"2015-08-05T15:33:11.332Z",
"updatedAt":"2015-08-05T15:33:39.738Z"
},
{
"ACL":{
"*":{
"read":true
}
},
"link":"category/the-fun-stuff",
"menu":"main",
"name":"The Fun Stuff",
"order":3,
"objectId":"WiPmXdhaOu",
"createdAt":"2015-08-05T15:33:44.667Z",
"updatedAt":"2015-08-05T15:34:06.058Z"
},
{
"ACL":{
"*":{
"read":true
}
},
"link":"category/the-nerdy-stuff",
"menu":"main",
"name":"The Nerdy Stuff",
"order":4,
"objectId":"Z0aSsnpV0B",
"createdAt":"2015-08-05T15:34:09.859Z",
"updatedAt":"2015-08-05T15:34:33.564Z"
},
{
"ACL":{
"*":{
"read":true
}
},
"link":"page/about-me",
"menu":"main",
"name":"About Me",
"order":5,
"objectId":"Gm35DOju7t",
"createdAt":"2015-08-05T15:34:37.759Z",
"updatedAt":"2015-08-05T15:34:55.387Z"
}
]
When I run this, I get 5 empty <a>'s, something like:
<a data-ng-repeat="x in template.menuObj" href="" class="ng-binding ng-scope"></a>
So I guess angular sees the 5 arrays, but somehow the keys are not caught?
EDIT: This is how the json object is created (via parse.com):
var Menu = Parse.Object.extend('Menu');
var query = new Parse.Query(Menu);
query.ascending('order');
query.equalTo('menu', 'main');
query.find().then(function(results){
console.log(JSON.stringify(results));
$scope.template.menuObj = results;
}, function(error){
// error-handling
console.log("Error: " + error.code + " " + error.message);
});
EDIT EDIT: Controller etc.
blogApp.controller('templateCtrl', function($scope, templateService) {
$scope.template = templateService;
var Menu = Parse.Object.extend('Menu');
var query = new Parse.Query(Menu);
query.ascending('order');
query.equalTo('menu', 'main');
query.find().then(function(results){
console.log(JSON.stringify(results));
$scope.template.menuObj = results;
}, function(error){
// error-handling
console.log("Error: " + error.code + " " + error.message);
});
});
templateService is a factory that binds a parent controller. It's important to note that before I started messing with parse.com for this project, the ng-repeat worked just fine when I retrieved ($http) a json object via PHP/MySQL.
EDIT EDIT EDIT: uploaded a screendump of console.log(results);
What's happening is that results is the array object, and you are assigning it to $scope.template.menuObj but the json array doesn't have a name. You could either give it a name:
"menuObj": [
{
"ACL":{
"*":{
"read":true
}
},
"link":"home",
"menu":"main",
"name":"Home",
"order":1,
"objectId":"aDcb0HUXwB",
"createdAt":"2015-08-05T15:29:05.948Z",
"updatedAt":"2015-08-05T15:29:11.915Z"
},
{
"ACL":{
"*":{
"read":true
}
},
"link":"category/the-interesting-stuff",
"menu":"main",
"name":"The Interesting Stuff",
"order":2,
"objectId":"znXfUF0kdJ",
"createdAt":"2015-08-05T15:33:11.332Z",
"updatedAt":"2015-08-05T15:33:39.738Z"
},
{
"ACL":{
"*":{
"read":true
}
},
"link":"category/the-fun-stuff",
"menu":"main",
"name":"The Fun Stuff",
"order":3,
"objectId":"WiPmXdhaOu",
"createdAt":"2015-08-05T15:33:44.667Z",
"updatedAt":"2015-08-05T15:34:06.058Z"
},
{
"ACL":{
"*":{
"read":true
}
},
"link":"category/the-nerdy-stuff",
"menu":"main",
"name":"The Nerdy Stuff",
"order":4,
"objectId":"Z0aSsnpV0B",
"createdAt":"2015-08-05T15:34:09.859Z",
"updatedAt":"2015-08-05T15:34:33.564Z"
},
{
"ACL":{
"*":{
"read":true
}
},
"link":"page/about-me",
"menu":"main",
"name":"About Me",
"order":5,
"objectId":"Gm35DOju7t",
"createdAt":"2015-08-05T15:34:37.759Z",
"updatedAt":"2015-08-05T15:34:55.387Z"
}
];
Or leave it like you have it, but the controller must be like this:
blogApp.controller('templateCtrl', function($scope, templateService) {
$scope.template = templateService;
var Menu = Parse.Object.extend('Menu');
var query = new Parse.Query(Menu);
query.ascending('order');
query.equalTo('menu', 'main');
query.find().then(function(results){
$scope.template = JSON.stringify(results);
}, function(error){
// error-handling
console.log("Error: " + error.code + " " + error.message);
});
});
And the view like this:
<body ng-app="blogApp"><!-- angular.module('blogApp', []); -->
<div ng-controller="templateCtrl" >
<nav ng-repeat="a in template">
{{ a.name }}
</nav>
</div>
</body>
But in the case you want to work with it as you have it you should do it this way:
<body ng-app="blogApp"><!-- angular.module('blogApp', []); -->
<div ng-controller="templateCtrl" >
<nav ng-repeat="a in template.menuObj">
{{ a.get('name') }}
</nav>
</div>
</body>

Categories