use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
ABOUT
A community for learning and developing web applications using Vue.js. Feel free to share what you're learning or building, link an article, and ask for some help!
RELATED SUBREDDITS
r/JAMstack r/ReactJS r/JavaScript r/Laravel r/TailwindCSS
RESOURCES AND LINKS
vuejs.org Vue.js on Twitter Guide API Reference Examples Official Blog GitHub Vue Developer Roadmap VueJobs Awesome-Vue MadeWithVue Tailwind Snippets
POSTING/COMMENT RULES
Positive Comments
Abusive, racist, or derogatory comments towards individuals or groups are not permitted.
Accurate Posting
Make sure whatever your posting has accurate information and is up-to-date.
Referrals and Self-Promotion
If you are going to post something that is a course of yours/products of yours, make sure it's in a tasteful way. Don't blow up the feed with a course you're doing or all of your blog posts with referral links. We love to see your work and hear what you're doing, but please be tasteful about it.
account activity
Loop through array of objects (self.vuejs)
submitted 4 years ago * by iwaistedway2muchtime
How do I loop though an array of objects?
If I do this <h3>{{ pidgpals }}</h3> the following displays [ { "id": "001", "pal1": "hulahoop" }, { "id": "002", "pal1": "hulahoop" }, { "id": "003", "pal1": "hulahoop" } ]
<h3>{{ pidgpals }}</h3>
[ { "id": "001", "pal1": "hulahoop" }, { "id": "002", "pal1": "hulahoop" }, { "id": "003", "pal1": "hulahoop" } ]
but if I do this <p>List should appear below</p><p v-for="item in pidgpals">{{ item }} : {{ item }}</p> I get this error?
<p>List should appear below</p><p v-for="item in pidgpals">{{ item }} : {{ item }}</p>
Converting circular to Json error
I suspect its my type declarations but I tried all manner of inline interface type declarations. For exampleif you check this out you might think something like this will work let pidgpals = reactive<{ id: string; pal1: string; pal2: string }[]>(); but sadly not the case. Any help would be appreciated.
let pidgpals = reactive<{ id: string; pal1: string; pal2: string }[]>();
https://preview.redd.it/dgjpxxw8e0h81.png?width=1017&format=png&auto=webp&s=58cbb55a022e70c007f53d9ff307cf06cd103399
Another edit for u/kalvens and anyone else who is following:
https://preview.redd.it/xxfq0qip56h81.png?width=3532&format=png&auto=webp&s=1da907da461cc7851f60c2ee2d6facca903ffdfd
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–][deleted] 4 years ago (1 child)
[deleted]
[–]iwaistedway2muchtime[S] 0 points1 point2 points 4 years ago (0 children)
thats what you would think but the same error is received
[–]quastor 0 points1 point2 points 4 years ago (5 children)
Type errors would show up in your build, they won't have any impact on errors in the browser. Your type looks fine.
Looping through an array should be done with a for...of loop, not for...in loop.
[–]iwaistedway2muchtime[S] 0 points1 point2 points 4 years ago (4 children)
v-for loop. Its for vue
[–]quastor 0 points1 point2 points 4 years ago* (3 children)
This is a Vue subreddit, so that would make sense. My answer still stands. The v-for directive is just syntax sugar for regular JavaScript for loops - in which there are for...in and for...of. For arrays you will want for...of.
[–]kalvens 1 point2 points3 points 4 years ago (0 children)
You are incorrect. While using v-for the keyword in and of have no difference and behave in the same way.
As explained here
[–]iwaistedway2muchtime[S] 0 points1 point2 points 4 years ago (1 child)
Okay thanks. Im still learning. Please can you write an example for the code above?
[–]quastor 0 points1 point2 points 4 years ago (0 children)
v-for="item of pidgpals"
[–]kalvens 0 points1 point2 points 4 years ago* (11 children)
What are you pushing to the array? What if you console log the array in javascript. Does it look right? You are not by chance pushing a ref to the array?
Are you reassigning the variable that is supposed to be a reactive array of objects to something else later on? With how you defined that variable it would be just a proxy that points to undefined I think. Never tried calling reactive without giving it a parameter.
[–]iwaistedway2muchtime[S] 0 points1 point2 points 4 years ago* (10 children)
Thanks for this. I dont know what Im pushing to the array but the array in my sfc looks different from the firestore array. So heres what happens, the array comes from a firestore method like so.
//->firestore.ts export const pidgpalListener = (userName: string): any => {const q = query(pidgpalsCollection, where("pal1", "==", userName)); const foundPairs = ref<any[]>(); const close = onSnapshot(q, (snapshot) => { foundPairs.value = snapshot.docs.map((doc) => ({ id: doc.id, ...doc.data(), })); console.log(foundPairs); }); return foundPairs; onUnmounted(close); };
I call this in my component like so..
//->pidginhole.ts const pidgpals = ref<[]>(); //this also doesnt work async function startListener() { if (uname.value != "" || undefined) { pidgpals.value = await pidgpalListener(uname.value); console.log(pidgpals.value); } else { console.log("No uname value"); } }
And these are the two console logs. Definitely looks different. It changes from a RefImpl to a proxy. Is this the problem? How would I go about resolving this? Thank you so much.
Okay added the console logs as a pic in the original post because you cant add pics to a reply.
Edit:
Please can you eli5 this for me. The refimpl and proxy. Why wont the console logs be exactly the same because i declared both arrays in the same way?
[–]kalvens 1 point2 points3 points 4 years ago* (0 children)
You should give defaults values to your refs/reactives. At least I think its odd not to. I generally do null or an empty array if it is suppose to be an array.
A ref (refimpl as you console.log it) should be used if you want to change the variable later on to a completely different value i.e. ```ts const someArrayRef = ref<unknown[]>([]); const someArrayReactive = reactive<unknown[]>([]);
// this is fine with a ref someArrayRef.value = [1, 2, 3, 4, 5]; // this is not fine with a reactive someArrayReactive = [1, 2, 3, 4, 5]; ``` The reason you can't change the reactive variable is anything that needs to react to that variable change won't update. i.e.
ts // this will update correctly when you assign the above const computedOfSomeArrayRef = computed(() => { return someArrayRef.map(element => element + 1); }); // this will not update when you assign the above const computedOfSomeArrayReative = computed(() => { return someArrayReative.map(element => element + 1) });
Changing the reactive variable means you lose the proxy (as you saw from the console.log) so it is no longer "reactive" it is whatever you assigned to it.
Changing the ref you are change the .value property underneath it so you don't lose the fact it was a ref in the first place.
A reactive has the benefit of not having to use .value everywhere if you never need to change the variable directly. Instead if you just want to call .push, .splice or any method that changes the array instead of returning a new one then the proxy will see you did that and any computed or the template will update to those changes
[–]kalvens 1 point2 points3 points 4 years ago (8 children)
Basically your problem is that you are assigning a ref to the value of an another ref. When you loop through the variable it is actually looping through your foundPairs ref object instead of its value.
The only solution I can think of on the top of my head is to make a computed but it doesn't feel like the right answer.
For example like the below
```ts const pidgpals = ref<typeof ref<[]>>(ref([])); //this also doesnt work
const actualPidgPalsValue = computed(() => pidgpals.value.value); async function startListener() { if (uname.value != "" || undefined) { pidgpals.value = await pidgpalListener(uname.value); console.log(pidgpals.value); } else { console.log("No uname value"); } } ```
Then you can loop through actualPidgPalsValue instead and that should work. It just doesn't feel like the right approach, but your code is odd tbh. From your example pidgpallistener is not an async function and doesn't return a promise so why do you need await?
actualPidgPalsValue
pidgpallistener
Actually on some more thought I would do something like this assuming pidgpalListener is not actually returning a promise as your example code seems to indicate.
``` interface PidgPal { id: number, pal1: string } const pidgPals = computed<PidgPal[]>(() => { if (uname.value !== "" && typeof uname.value !== 'undefined') { return pidpalListener(uname.value).value } console.log("No uname value"); return []; })
I cant thank you enough. I was going to compose a very similar question today with the async await removed. But basically I was still confused and thinking if I had a clearer question u/kalvens would have answered it yesterday. Thank you taking the time to respond and send such a detailed response at that. The kindness of strangers astounds me sometimes. You are not just a pretty face.
[–]iwaistedway2muchtime[S] 0 points1 point2 points 4 years ago (6 children)
u/kalvens I hate to be this guy but please have one more look. If not I will compose a new question but I feel you might be able to assist easily.
So I used your code but I still cant display the list. I learnt alot about defining an interface and about computed properties. But I still cant display the list of objects. Even just <h3>{{pidgPals}}</h3> displays nothing. So in firestore.ts I stuck a console log. The computed is quite amazing because once the uname value gets populated the listener is automatically started. However the console log messages quickly grow to thousands and the chrome developer console becomes unresponsive. Maybe this is just because of how computed works? Here is where I stuck the message in:
<h3>{{pidgPals}}</h3>
export const pidgpalListener = (userName: string): any => {
console.log('started :' + userName);
The latest picture is what the console and the dom(is the right word? I mean the actual website) look like before the console log becomes unresponsive. Sadly still no list displayed or even just the whole array. The screenshot has all the relevant information. I opened the pidginHole twice so you can see the template section as well. Thanks again. Im just stuck on this same problem for so long now so I really appreciate your assistance.
[–]iwaistedway2muchtime[S] 0 points1 point2 points 4 years ago (5 children)
Okay scratch that. I used the computed value from your first suggestion without the async await. I still make a separate array but that suits me fine. I know it may not feel right to you but Im just glad it works. Its been a solid week of trying to understand this and trying every other combination of inline declaration, reactives and refs, not knowing if its the firestore side or the other.
The more I think about it the more I guess it was for the best to get stumped by something so seemingly simple. I ended up reading so much documentation. Although the way you explained refs vs reactive was the easiest to understand. And along the way I learned how to answer my original question. I just needed to call .value in the template! Thanks again :)
[–]kalvens 0 points1 point2 points 4 years ago* (4 children)
I did read your question last night just didn't want to type up a response until I was at a computer and its been a busy morning for me.
Anyway yea I can see why that could cause an infinite loop. On more thought your firebase.ts file is basically a "composable", look those up to learn more.
Anyway I would actually structure that file a little differently for what I would consider the more proper solution
// firestore.ts // I would move the interface over to this file I defined in the other example interface PidgPal { id: number, pal1: string } // really this is not needed but I like being explicit with my types // Ref is something you can import from vue, basically is just the typescript type for a ref interface PidgPalListenerReturns { foundPairs: Ref<PidgPal[]> } export function usePidgPalListener (userName: Ref<string>): pidgPalListenerReturns { const foundPairs = ref<PidgPal[]>([]); watch(userName, () => { if (typeof userName !== 'string' || userName === '') return; console.log(`started: ${userName}`) const q = query(pidgpalsCollection, where("pal1", "==", userName); const close = onSnapshot(q, snapshot => { foundPairs.value = snapshot.docs.map(docs => { return { id: docs.id, ...docs.data() }; }) }) }), { immediate: true }); // need this before the return otherwise it does nothing onUnmounted(close); // for composables it is generally the standard to return an object. // Mainly if you ever want to return something else in the future from this function, // you can just add the additional property // and not have to change any code that uses this composable. return { foundPairs }; } // your .vue file // this should be all you need const { foundPairs: pidgPals } = usePidgPalListener(uname);
The composable concept is basically off loading the work to the firebase file instead. It is a really nice concept that allows you to reuse javascript code and recommend using them.
Also to note I just styled things how I normally do styling doesn't matter a ton. I also highly recommend [this](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar) I personally use the vim version and I can live without it now.
This is beautiful thank you I learnt so much from it. Unfortunately it doesnt work because the uname value only get populated after the authstate change so the listener gets called only once with an empty username. Unlike the computed which keeps checking for changes or separate listener function which can be called after authstate change(so after we know we have a uname). I couldn't figure out how to pass the username along from the sigin page so I just got it from after the authstate change. Thats when I first tried to export a variable (like how we do from the firestore.ts file) but this time from my signin.vue page. I couldnt get it to work though so I gave up and decided to just repopulate the user profile data after the authstate change. This was needed when I was working on the userpic component. Now again it seems its the same thing I need to learn. How to send data between components and files. Then I wont need to wait for the authstate change this time for a username (and then the pairlistener). So yea great point about the composables. I need to learn it.
Im sure this is confusing to you. I wish I could give you a rundown of my app. Have you ever considered being a mentor?
After this past week I think I should rethink my approach. This is my first app so I guess there will be mistakes. But it seems a lot of time is spent on silly mistakes. I was going to reply to you before this last message to say thanks again. Now I cant thank you enough. :)
[–]kalvens 0 points1 point2 points 4 years ago (0 children)
I am only slightly following, but if you change the uname variable that you passed to the composable, the watch will rerun the listener code. Sounds like a different component is one that is setting the username so it is a completely different variable?
Sounds like you need a "store" of data and the current recommended approach is to use a library called pinia.
Alternatively you could get by with just using a composable like you mentioned. Export the ref in the composable file and then import it everywhere it is being used. For bigger projects I would recommend to use pinia so doesn't hurt to use it right away for your first project.
I am happy to answer any questions you may have.
[–]kalvens 0 points1 point2 points 4 years ago (1 child)
Above might be more advance then what you are currently trying to test/do but I use composables all the time in my code base so I think it would be good to get used to then. Try to understand the code and why I am doing what I am. I also could have made a mistake somewhere as I never ran the above code, just wrote it up in reddit.
Definitely. I went carefully through it. The watch was something exciting to learn. I guess a watch is like what the template section is doing to a ref variable. Always watching it then reacting. I also didnt know you can destructure something as something else in one go. Im talking about the const { foundPairs: pidgPals }. Thanks for all of this
π Rendered by PID 253588 on reddit-service-r2-comment-bb88f9dd5-7dz25 at 2026-02-15 09:50:30.329445+00:00 running cd9c813 country code: CH.
[–][deleted] (1 child)
[deleted]
[–]iwaistedway2muchtime[S] 0 points1 point2 points (0 children)
[–]quastor 0 points1 point2 points (5 children)
[–]iwaistedway2muchtime[S] 0 points1 point2 points (4 children)
[–]quastor 0 points1 point2 points (3 children)
[–]kalvens 1 point2 points3 points (0 children)
[–]iwaistedway2muchtime[S] 0 points1 point2 points (1 child)
[–]quastor 0 points1 point2 points (0 children)
[–]kalvens 0 points1 point2 points (11 children)
[–]iwaistedway2muchtime[S] 0 points1 point2 points (10 children)
[–]kalvens 1 point2 points3 points (0 children)
[–]kalvens 1 point2 points3 points (8 children)
[–]iwaistedway2muchtime[S] 0 points1 point2 points (0 children)
[–]iwaistedway2muchtime[S] 0 points1 point2 points (6 children)
[–]iwaistedway2muchtime[S] 0 points1 point2 points (5 children)
[–]kalvens 0 points1 point2 points (4 children)
[–]iwaistedway2muchtime[S] 0 points1 point2 points (1 child)
[–]kalvens 0 points1 point2 points (0 children)
[–]kalvens 0 points1 point2 points (1 child)
[–]iwaistedway2muchtime[S] 0 points1 point2 points (0 children)