---
tags: mstu5013, tinker
---
# Shared Tinkers: Summer 2021
---
## Tinker Slides Writing + Reading
**General Feedback**
- When thinking about reading and writing one way to go about it is to break down the user experience computationally. What does the user do first? How does the system respond? What does the user do second? How does/SHOULD the system respond? By thinking through the UX sequentially, you should be able to get a good sense of when in the user-flow a read operation must happen (i.e. so that the content is available expediently) or when the app should do a write operation (i.e. in a way when it is appropriately clear and aligned with user intentions.)
- When you name a collection, a good convention is to use PLURAL naming. Collection Animals is better than Animal as it represents a collection of stuff. Then you can refer to the document as the singular. It makes it much easier for others to understand if you're referring to a collection or document.
- Also, name it something that conceptually describes what the data represents.
- It's about communication.
- Example: `let playersRef = db.collection('olympics');`
- Is this a collection of `player` documents? Or is it a collection of `olympicEvent` data documents? (E.g. `{ year:2021,site:"Tokyo" }`).
- While it's nice to start off with understanding basic read/get and write/set commands, using REALTIME features of Firebase is soooo much better... makes using components and DBs soooo much easier...
- I like how one group mentions - "We should think about the user story" before thinking of the DB manipulation functions. It's well said.
- Remapping the real DB data into your conceptual terms is a great way to illustrate/understand this yourself. :thumbsup:
- If you want me to look at your actual database, don't forget to include me as a collaborator in Firebase configuration. Most of the time, I can infer what the data looks like from your code though.
- Using doc ids for :keys is smart, but in Vue 3 I think we no longer need to do this key thing. I mean, we can get away without it in Vue 2 to some degree as well so maybe just old news.
- `snapshot vs querysnapshot` In short, they are conceptually the same in that they are both objects that wrap meta data and actual raw data sent to us at a given point in time from the DB. However, snapshot is associated with DOCUMENT snapshots while querysnapshots are associated with COLLECTION snapshots. Since documents are always single entities, a snapshot won't support things like `forEach` (no need.) A query - we assume we are querying for multiple documents (even if we get only one or none) so it has special properties and methods that are helpful for this context. Keep in mind that the important thing here is if you do a `docRef.get()` you'll be working with a document snapshot while if you do a `collectionRef.get()` or a query `collectionRef.QUERYCODEHERE().get()` you will be dealing with a querySnapshot. However, you can name this anything you want in your callback. Many like to name the parameter in the callback `snapshot` and `querySnapshot` but I've seen `docSnap` vs. `colSnap` and I've even seen some lazy programmers call everything a `snap` regardless of whether it's a doc or collection callback. I think it's good to be explicit to communicate so I like some distinction: `docSnap` vs. `querySnap` or something is like that fine.
- Brings joy to hear you all using highly technical and precise terms to describe programmatic/computational phenomenon. Sound like programmers.
- So I somewhat forget whether I do this or not... but it's good form to always have a `catch()` if you use a `then()` Keep in mind, `catch()` is NOT for if there is no data. You can have no data and the promise can be considered successfully resolved. (i.e. I did a query, the results turned out nothing!) `catch` is for errors.
```javscript=
someRef.get().then(snap => {
// code if promise is resolved
}).catch(error => {
// code if promise is rejected
})
```
- I admit I lazy out of this one a lot as I'm very "optimistic" that the FB promises will be fulfilled. But not having a catch statement is an eventual trap that will get me/you in trouble one of these days.
- If you have a `v-for="something"` make sure you at least initialize `something` in your data as an empty array `[]` or it won't like it.
- Hm. Interesting fundamentals insight. In Javascript, object properties we tend not to have double quotes wrapping the property name. But we can. `{"prop":value}` Javascript out of convenience or mercy can interpret `{prop:value}` as a property due to the syntactical pattern. However, using quotes allows you to do things like this:
```javascript=
// ERROR thinks the hyphen is a minus operator
let x = { my-idea: "$1,000,000" };
// LEGAL
let y = { "my-idea": "$1,000,000" };
// ACCESSING - ERROR, thinks minus sign
y.my-idea;
// LEGAL
y["my-idea"];
// BEST
let z = { myIdea: "$1,000,000" };
z.myIdea;
```
- Honestly, it's just more consistent, common to not use hyphenated property names as it's extra typing work. But there might be times where it's useful. Better just to use camel case and object dot notation, and be done.
- That said: JSON (Javascript Object Notation) --- the raw data that gets sent over the wire looks like a Javascript Object, but the property names MUST be wrapped for correct syntax. JSON is inherently a string, and when we transfer data over the network, we're essentially sending strings (usually.) Even things like: `{myProp: value}` would in JSON be:
- `"{\"myProp\":\"value\"}"` or...
- `'{"myProp":"value"}'`
- with the value only wrapped in quotes if it is a String. Note how the whole JSON representation itself is a string. JSON is javscript object NOTATION.
- When you `console.log()` things and are working with async code, don't forget that the callback will happen after the code outside the callback. Common gotcha.
```javascript=
this.test; // undefined
console.log("A", this.test);
myRef.get().then(snap => {
this.test = snap.data();
console.log("B", this.test);
});
console.log("C", this.test);
// "A, undefined", "C, undefined", "B, docData"
```
- Note: Order of promise based stuff isn't:
- `get()` > `then()` > `catch()`
- It is more accurately:
- `get()` > `then()` OR `catch()`
- You can even do fancy things like these:
```
get().then().then().catch().finally();
get().then.().all().finally();
```
- See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
- Some of you might benefit from learning how to do a `db.batch()` operation: https://firebase.google.com/docs/firestore/manage-data/transactions which is pretty cool if you want to reduce the number of times you hit the DB, but have multiple writes you want to execute.
- With numbers and strings... if you're taking user input via `v-model` and you want numbers, don't forget to use the modifier: `v-model.number` Your Database cares about data type... so if you send the data `"100"` it's going to treat it as a string. Not a number `100`.
- If you want to see what a `catch(error => {})` does, try loading the page, unplugging your internet, then executing a database function.
## Tinker Slides FS Inro + Data Architecture
**General Feedback and Comments**
I'm constantly impressed by the kinds of questions you guys generate through your work on this stuff. Not just limited to Firestore, but also Vue, and basic JS (vanilla) fundamentals. And it heartens me to see when you guys show the results of your own independent research into these fresh areas. Lots of great references.
Also, if you want to show me your firebase databases themselves (helpful since I do click on links in your tinker) please make sure to add me as at least a viewer under your firebase project >>> Users and Permissions. Add my tc email. :thumbsup: Only thing I ask is your project names aren't MSTU 5013 Classwork or MSTU 5013 Playground. They all show up on my dashboard and it gets hard for me to find which one is mine. PS - same goes for any Google Docs references you want me to check out. Permissions.
- So, some of were talking about Firebase analytics... just note that that is another suite of tools Firebase offers and it's just part of the default copy paste they offer because I suppose, they want you to use it. Maybe interesting for production apps but for our purposes, we just want to replace it with the firestore package. In a real app, you might just add both. Firebase is an additive suite so you only need to import the parts of FB you need for your app. For our purposes make sure you import BOTH:
- `<script src="https://...firebase-app.js"></script>`
- `<script src="https://...firebase-firestore.js"></script>`
- Anything else is only useful if you decide you want to go beyond what we cover and use. That said, there are some interesting areas some people might want to explore over the next 2 more weeks...
- Firebase auth (for authentication / login)
- `<script src="https://...firebase-ui-auth.js"></script>`
- Firebase storage (for file uploading and storage)
- I know, database isn't storage? Databases generally are designed for little data like strings, bools, nums, etc. Files - by comparison are huge so it's common that these are actually saved in a separate storage system then linked to the database somehow. For example:
```
I create a user profile data object (i.e. name, age, imageURL)
When I go to set the user profile into firestore... before I do that I upload the image file.
When the image file upload is complete, I get back information about the file... things like the URL LOCATION.
I use that URL LOCATION to fill in the imageURL property of the user profile data.
Then I go ahead and set the user profile data into firestore... and now my data object has a link (in plain text) to the storage object.
```
- A great inquiry - why use mounted? Couldn't we use methods in which we define and execute our Firestore database get? The answer to this is you totally could. The only caveat is, with methods you would have to somehow automatically call it at the start of the application if you wanted your application to start with populated data. Think Twitter. You load the feed page and the feed is already populated. This is because they grab the data as soon as the main component is mounted to make the experience seemless. They could create a button you push to get that first list of tweets.. but that's not very friendly. Thus, using something like `mounted()` to get that first database get helps.
- Ha. Some of you guys have found out that to add a meaningful sample data set into Firestore, it's actually easier to create a small JS script rather than manually enter information into the FB console. I don't mind either way but when you start thinking "coding this is faster" you're well on your way to being a coder.

But also this...

- Some of you guys are picking up the gist and already writing sample read/write code... that's great but also no need to rush. We'll spend plenty of in-depth time with reading/writing ideas and techniques next.
- The system/user query roleplay scripts are quite fascinating and telling. :thumbsup:
- Also, I love that some groups created a data structure, then went through the process of rethinking whether there was a simpler way (procedurally) to get the data they want. Like I mention a lot, with databases reading writing isn't the hardest part. The hardest part is thinking of the data architecture design for the purposes you want to fulfill. There are multiple correct solutions! So you don't have to worry too much at this point, but this is what separates a great database from a mediocre one. Make your life easier with good design.
- ALSO - naming of your collections. Some of you'all found that what is intuitive naming for you, might not be intuitive naming for your team. This is a GREAT discovery. One way the instructors and I can tell whether someone is beginner or advanced, (or is producing original or copied code... lol,) is just by how they name things like their variables, functions, data objects and collections. Experts follow conventions and customs, but also can create succinct and clearly descriptive naming schemes. I think part of this is a somewhat directional approach mindset. When I name things - I'm not only thinking about what makes sense to me but also what would be easy for others to understand.
## Tinker Slides Vue 2C + 3
**General Feedback and Comments**
Something minor which some people are doing consistently and others not so much. In both Slack and HackMD, basic markdown syntax applies so you can use that to better emphasize your articulations.
Wrap inline code in single-backticks \` :
- This is `let code = "inline"` code.
Wrap block code in triple-backticks \`\`\` .
```
let block = this;
function formatted(msg) {
return msg.includes("```");
}
```
You can make block code syntax highlight for JS or HTML etc by adding `:javascript` or `:html` after your opening \`\`\` (HackMD only, for Slack use code snippets.)
```:javascript
let vue = new Vue({
data: {
stuff: true,
other: 777,
alt: "zoomies"
}
});
```
Add an `=` after the `:javascript` like `:javascript=` to get line numbers.
```:javascript=
let x = this;
let y = that;
let z = those;
```
This is particularly helpful in making readable slack messages in `#ask-us-code`. Also good etiquette when posting code in other places/communities like Stackoverflow.
**Actual Vue Feedback**
- Good to see use of modifiers like `v-model.number="age"`. HTML automatically stores all input values as strings which makes things like number operations and boolean testing more unintuitive. (There's a reason for this but it's just how it is.) So don't forget to make sure to use modifiers to convert input values to the data types you need for your computations etc.!
- I'm seeing some groups come up with MULTIPLE solutions to some of the challenges presented. Yes - like mentioned before - programming is often about many different possible solutions and doing / evaluating (thinking through) the range is a sure way to understand the nuances of which techniques help/hurt pros/cons in which situations. Also true of groups who are actively coding a solution first, then looking at my answer, then processing the comparisions and contrasts. Your insights about your own code as well as new curve-balls I introduce are amazing. not to mention the links you're including to the extra leg-work-study you've put in to understand my curve-balls.
- So `EventBus`. There's something mystical, magical about this and at the same time, not. `Event Bus` is just another common name for an event aggregator, which is just a name of a technique used where a single object is like the central hub of communication. (Also see publish-subscribe or PUB-SUB) Whereever it is stationed it can trigger and listen for events and talk pass that information to whatever is "subscribed" to that event bus. Essentially it's just an object that can talk and listen to itself but you clone it and place it all over the place. Clone A can mumble to itself near David and David gets info. Clone B mumbles the same thing near Jin and Jin gets info. etc. (Oversimplified.) In Vue, Vue components themselves have abilities to trigger and handle events. So when we do `const EventBus = new Vue()` at the global level, we have access to the variable EventBus in any component. Thus, by placing this EventBus object (just a Vue component but we never use any other aspect of the component, only event triggering and listening) in a component, we have a "radio" of sorts through which components can send info across the network of components. It's a common technique but it has critics. For simple things like our projects I think it's fine and not to think too deeply. But if you have a HUGE project using this technique might be unsustainable. (Imagine keeping track of all these connections of data talking from one comp to another...) In reality, when our data between components starts to get more challenging - Vue offers an add-on called VUEX which helps with this sort of thing. Don't overthink it, but watching the **short video** on the official Vuex page might give you another idea of how advanced programmers think about and deal with data across components: https://vuex.vuejs.org/ Note this is another plug to checkout the Vue Mastery tutorials. :grin:
- Props and naming can be confusing. Make sure you understand the connection between references because in reality...
```:htmlmixed=
<root>
<comp :user-prop="userData" />
</root>
let app = new Vue({ // e.g. root
data: {
userData: { name:"Jin" }
}
});
let comp = new Vue.component("comp", {
props: ["userProp"],
methods: {
example() { console.log(this.userProp); }
}
});
```
... people would code using the same name across the board in different places out of convenience since Vue and the programmer knows through the syntactical pattern which reference refers to what.
```:htmlmixed=
<root>
<comp :user="user" />
</root>
let app = new Vue({ // e.g. root
data: {
user: { name:"Jin" }
}
});
let comp = new Vue.component("comp", {
props: ["user"],
methods: {
example() { console.log(this.user); }
}
});
```
- Analogies. Okay, one group had a really delightful analogy comparing event emitters like Paul Revere. (Another about children asking parents for milk and potty time!? :laugh:) Different analogies will work for different folks. I love this technique of making sense of things. By creating analogies (even to unseemingly code-unlike concepts) it cognitively forces you to conceptualize things by linking them to things in your exiting mental models and this is a great way to not only make sense of likeness/dislikeness of patter concepts but to challenge them. How quickly you can come up with an analogy and how directly it maps to the concept is a function of deep understanding.
- My analogy is that components come standard with walkie-talkies. And every component, like a good solider has a squad name. So with event emiting and handling, usually parent solidiers (ranked higher up officers) have the comm codes for their subordinates (children lower hierarchy) and can hear the chatter emitted from their squads to officers. With event bus - that's like central comm and special satellite comm devices (the Event Bus) are provided (sometimes) to specific groups (components). Any squad, solidier, officer with a special satellite comm device can send and hear messages to central comm. But each squad, officer, is given a special orders to listen to specific chatter (custom event name). So Squad A might be listening for event name `"assault"` and Squad B might be listening for event name `"defend"`. Any chatter that comes through if it doesn't have the special order is ignored. But if the special order is included, they are LISTENING for it, they can handle it as planned (via the handler function). Stories are great ways to remember things and have a rich cognitive study/history.
- Aside: Thank you for noticing that even the very complex examples I create have a very deliberate focus on the main concepts I'm trying to get across. It's always a fun effort to think about what is the `Math.max()` I can challenge you all with given basically only the tools we've learned about. Real apps obviously use every tool in the book to produce rich examples. But this can be more load than beginner programmers can handle. From a learning design perspective, this is a balance you need to think about. So creating examples that actually mean something and are humanly interesting with only a subset of concepts is always a dilema! :cat:
- Where to use `this` keyword. In your templates - `this` is always assumed. So instead of `<span @click="this.x">{{ this.y }}</span>` we can do `<span @click="x">{{ y }}</span>`. It's inside our component JS like in `data, methods, computed` we need to reference `this` component thus `this.x, this.y`
- Don't feel bad about errors around camelCase kebabCase and props case-conversion. I still make this error and smack my face over it all the time.
- Templates and logic. So templates have Vue logic capabilities through directives like `v-for, v-if` etc. And anywhere you are using a Vue directive, you can insert plain javascript.
- `<div>{{ javscript here }}</div>`
- `<div :class="JS here">`
- `<div @click="JS here"`
- etc.
- But I recommend that you don't do too much Javascript inside v-bound `" "` stuff. If you have complex logic starting to make your template harder to read, move that code into a computed or method and just reference it. Examples:
- `<div @click="x > 100 && y < 50 ? methodA : methodB">PUSH</div>`
- vs.
- `<div @click="doAorB">PUSH</div>`
with `doAorB` logic defined in a computed.
- The purpose of templates is to make it readable. That means just enough logic that the reader knows how the DOM and computations relate, but not so much that it disrupts the structural clarity.
- For those of you who wonder why certain JS math which should give a nice clean decimal ends up something like `0.50000000000000001` etc. https://stackoverflow.com/questions/1458633/how-to-deal-with-floating-point-number-precision-in-javascript
It's just a thing. Most common way to deal with it is to take that number and cut it down to something presentable. E.g. to convert a number to a string to x places: `var num = 3.14012345;
var numStr = num.toFixed(2);` will yield `"3.14"`. No need to do some of the fancier things in the SO post although it's interesting to peruse.
- Again, I really appreciate those who are writing up the challenges and mistakes you made and what you did to go about understanding it. These really help me understand which areas to write commentary about, what new samples to create, etc. I can tell a lot about people's understanding not just by how they come to correct answers but how they come to incorrect ones. For example, in some ways when someone says 1 + 1 = 3, this is correct in the sense that in someone's head SOMETHING is hooked up in some way to yield this result. No one says/gives a wrong answer thinking it's incorrect (usually.) There's always some sort of underlying reason. The expression of error and how they came to that expression reveals some of this underlying reasoning.
- While I almost never give answers - this one is a fun one. How many Vue components are there? Definitely not 2, 3 meaningfully, but **4 actually.** This one isn't that important, but it stumped the majority of groups.
## Tinker Slides Vue 2A + 2B
**General Feedback and Comments:**
Your use of the of the Vue devtool, observations, and manipulations are inspiring confidence you're understanding the most fundamental conceptual shift in this type of programming framework. We feel pretty good about where most of you stand. Most tinkers are very thoughtful and rich with insights and process. To note, these assignments aren't meant to force you into any one way to go about it. But it is good to write-out and articulate your thought process using the language as a way to solidify the abstract concepts. Even focusing only on the most challenging and poinant moments of your journey can be helpful so I encourage you to think about how best to get something meaningful out of these exercises. Lastly, thanks for including links, images, sample code, clean communicative formatting to help me understand where you all stand as a class better. It really helps.
- One small thing about `v-if-else` vs `v-show` that is significant is that `v-if-else` will actually mount/unmount the component from the DOM. (The template HTML will be added or removed). `v-show` will never remove the template HTML from the DOM, just behind the scenes toggle a css rule `display: none` or `display:block` for example. It's somewhat of a performance thing, it takes some work to add/remove things from the DOM so if it's something that will be actively toggled, just use v-show to avoid the performance issues of manipulating the DOM. But in truth, the issue is probably small given the kinds of things we work with.
- People like rainbow themes for producing exploratory stuff it seems.
- I'm very happy to see you guys using not just the standard `v-for="item in collection"` syntax pattern but also the following patterns:
- `v-for="(item, index) in collection"`
- Think of using this if you want to use the index/position as a way to compute things. Since index always `++` starting at 0, its a good way of doing computation that requires a linear factor. E.g. `0 * width = 0, 1 * width = 1, 2 * width = ...` so you can do things like dynamically scale things linearly, dimensions, colors, you can be creative with this.
- `v-for="n in range"`
- This one is good when you don't really care about the items in the collection but you need to repeat something a given `n` number of times.
- On Forms and Submit... so HTML forms have a default behavior of redirecting to a new page once a form is officially triggered with a `submit` event. This is from legacy behaviors when we didn't have technology that could send and receive data from a single page and so all data had to be submitted and received via going to a new page (send data through URL) and landing on a new page (getting data from the server as part of the page.) We generally live in a world where apps can send/receive data asynchronously without jumping around. So if you use the `submit` event to signify "end of form" etc. you can prevent the default redirecting behavior by using the vue modifier `.prevent`
- VUE: `@submit.prevent` add to the event listener
- Native: `function callback(event) { event.preventDefault(); }` add to the callback function.
- To remove multiple todo items: There are many ways to do this but what I usually do is make a `computed` that will automatically create/update a separate list array of only items checked `done:true`. As users check things, this computed array always contains all `done:true` items. Then when the user says "delete all done" your computed list knows all the items that should be spliced out/removed from the original array.
- An even easier way is you used computed to keep a list of only not done items `done:false` and when people "remove all done" you simply replace the existing original array with this computed copy that only includes the ones you would keep. Think about this. It's two ways to solve it from opposite directions, but one is super super simple to implement.
- My heart sings every time you all observe a moment that is framed in a data-state-driven sort of way. Glad to see you noticing this conceptual shift from the way we might have thought/programmed in 5003.
- Some of you all are making comparisons between one tinker example and others in novel ways. This is really smart. Comparing and contrasting exmaples is a really smart cognitive strategy.
- Flowers, Chocolate... Checkboxes. Good - many of you are making the keen observation of WHAT aspects are the data values that get pushed into the array due to `v-model`, distingushing the difference between the `value="data"` and just `plain text content` of the checkbox element context.
- While I think everyone has caught on with syntactical shortcuts based on how you're talking about things just to reiterate since in my slides I tend to use the full syntax but my examples I use shortcuts:
- `v-bind:ref` >>> `:ref`
- `onEvent` >>> `@event`
- Vue Devtool handy shortcuts: So many of you guys are using the vue devtool correctly but I'm getting a sense based on your process writeup you might be missing some handy shortcuts! Here are some...
- Rather than entering new numbers, you can do things like +/- to increment decrement through the UI. You can even do things like `shift` `ctrl` `+` to go up by 10s even 100s I think.
- Boolean values in the devtool can be checked through the UI to toggle true/false rather than typing true/false out.
- etc. So don't be afraid to play. You never know what feature you might discover that makes working with the tool that much more convenient.
- I've seen this pop up a few times through your examples (most teams wrote up the issue, played with it, resolved it) but what I want to emphasize is that you need to be very attentive to syntactical pattern structures. Libraries like this might expect certain syntax to be represented in certain data ways. For example:
- `:style="{ backgroundColor: 'red' }"` The way to think about this is when we style bind, we should think of binding in terms of an OBJECT. This is not the same as: `:style="backgroundColor:red"` as some of you have found. This has implications. For example, if we wanted to let a computed deal with a style in the following expression: `:style="myStyles"` you have to think based on the pattern, what kind of DATA should `myStyles` be? It should be an object. SO... therefore, then... the computed should also return an object. `computed: { myStyles() { return { backgroundColor:"red" } } }` Many curly braces here but you need to think interms of which curly braces represent which what data. (And in some cases, the curly braces here don't represent objects but rather the function body so you gotta be attentive to each thing and what it represents.)
- Trick: If you want to remove all items... no need to splice. Just replace the original array with a fresh (blank `[]`) array!
- Clarification: Using vue doesn't mean the dom isn't acted on manipulated, it just means WE don't have to explicitly do that. The underlying code of Vue will do this for us as long as we interface with Vue, making the right ref/data-state connections with the right directives to automate thsee DOM manipulations.
- Nested `v-for`. Super interesting and nice to see this exploration. Yes! You can totally loop through an array and then do another loop internally. The common usecase is something like a list of items with each item being an object, and the object having a list itself.
```
data: {
users: [
{name:"David", hobbies:["A","B"] },
{name:"Blake", hobbies:["X","Y"] }
]
}
<div v-for="user in users">
<ul>
<li v-for="hobby in user.hobbies">{{ hobby }}</li>
</ul>
</div>
```
## Tinker - Slides Vue 1B
**General Feedback and Comments:**
Overall I'm pretty pleased with how you're talking about Vue and related concepts. Esp. since this is just the first two parts. We'll continue to talk a lot about these concepts again and again so your articulations will continue to refine as you adjust your mental models of how all this connects and how the parts have more nuanced specifics. That said, here are general feedback thoughts I came up with as I read your articulations.
- Data vs. Computed: in general the idea is there. But I wouldn't say that data is stored vs computed is computed... yes computed will compute new values. But that computed value is temporarily "stored" or cached. However, computeds are smart and will recompute a new value automatically if one of the factors that go into the computed is changed. Nuanced point but something to keep in mind.
- Templates are the entire snippet of HTML that will be used to "plug in". Interpolation is the process by which values are inserted into a template via the {{}} double mustaches.
- Glad to see people are articulating the camel vs kebab detail when using props.
- One other thing about props that I didn't see much of across articulations. Props are one-way. In that you cannot change a prop from the child. E.g. if my component takes a prop `myNum` and the value is `0` I cannot change `myNum` to `1` in the custom comp accepting the prop. However, objects passed in as props are interesting. If I have a prop `myObj` which is `{id:"a"}` I cannot reassign that prop to a different object. BUT I can take that object and mutate the object by changing the `id` value of it to `"b"`. The difference is, you cannot change the original reference to a different / new object. But you can mutate the object itself.
- Being unsure of something is a-okay! I appreciate groups that mention this then go about talking through the process of where and why they think something. This is important in creating an initial model of understanding. (We'll be visiting these ideas again and you'll be adjusting your mental models.)
- One way of thinking of v-bind ... "we are binding an attribute to a JS expression" That expression could be a simple reference (e.g. in our data) or a computed property that gets computed if a dependent state changes, or just an equation or simple value. `<div :id="'x'">` is a legitimate binding. Pretty useless as the JS expression within the double-quotes is a single-quote-string "x" so it never changes. But legal. Normally, we're binding the attribute value to some state that is watched as it changes... and binding makes those state changes automatically trigger a view state reaction/update/change.
- Generally everything that happens in the browser is what we consider "front-end" and on the server... "back-end" but the idea of VIEW state being different than the COMPONENT state (model and logic) is a good way of differentiating the parts of this stype of program design.
- Interesting observation that in the root component we can define the data just by doing `data: {}` but in custom components we have to make data a function that returns an object `data() { return {} }`. It's a weird quirk of Vue 2.0 design but in Vue 3.0 - every component will do the data as function returning object thing `data() { return {} }`.
- Some of you have created some interesting unique offshoots of what was in the slides and I super appreciate this type of exploration.
- Some interesting thoughts on {{}} syntax of interpolating. This is actually customizable. If you go into the Vue configs, you can for example, change it to use something like <% %> to interpolate. {{}} and <%%> tend to be pretty common conventions for interpolating and I rarely see people changing this configuration but it is possible to make the interpolation symbols <!~&^$ $^&~!> if you so choose. But why? :woman-shrugging:
- Keyword THIS. I'm very glad to see people explicitly talk about the importance. When working inside templates, we can omit `this` keyword as the template associated with a component ASSUMES `this`. But you can include it {{ this.username }}. But we're lazy so we'd rather type less. That said, within the JS part of a component if we want to refer to data, computed properties, methods, props, of the component... do not forget `this` or it will only look for the reference within the function and not at the larger component level. Console can usually give a pretty clear error around this sort of issue.
- There are actually some other interesting "first level" properties of components other than `data, methods, computed` etc. If you're interested, check out `watch` and `filter`. I almost never use `watch` - it's really only useful in strange edge cases where computed or methods to change state wouldn't apply. But `filter` is an interesting one FYI.
- I mentioned this somewhat before but Vue, binding, interpolating... is basically about connecting parts of our template to JS expressions. So when you interpolate `{{ "any" + "JS" + "expression" }}` will work within. Same with the binding... `<img :src=" 'any' + 'JS' + 'expression' ">`. You can have functions, operations, concatenation. All JS is game. That said, you WANT your expressions to be simple so that the template is readable. If your expressions get too complex... try offloading all that expression code into a computed so the logic is separated from the template concerns which should be to communicate the intent succinctly.
- Mm. Good to hear people talk about the structure of Vue components. By using Vue you are agreeing that a Vue component (options) object `{}` has property names like `data, methods, computed` and that those are objects. And inside those objects, is where you can start customizing stuff.
- Defining components - the definition. Us coding what a component should look and act like. Instantiating a component is when that definition is realized into a live JS object. One way objects are instantiated is when you see the keyword `new`. But another... is once we have a component definition, and it is registered with Vue (vue is aware of this new component through the definition), it can be instantiated in parent components through the template `<my-custom-component>`. This in the template tells Vue it must instantiate a new instance of this component in JS and do the DOM attaching thing etc.
- BTW - you can derive computed properties from OTHER computed properties... Just sayin.
- About concatenation since several of you mention it specifically (which I found somewhat interesting.) Things like Vue should help us reduce having to concatenate. Instead of creating a string from concat and then sticking it into the dom... we only have to worry about the template and where to plug in data states. `<div>Cost is ${{ price }}</div>`. Also... template literals can really help us create strings without concatenation + signs. Actually, if you've ever used a template literal - you've been interpolating all along! The symbol to interpolate within a template literal is `${ data }` as opposed to `{{ data }}`
- Do we need to use HTML at all with Vue? I mean, I guess that depends on how you think of the HTML. Your HTML page could literally just be a single div that you attach Vue components to and the rest of the page generated by the templates defined within your components and sub-comps. But the templates of each component, are eventually going to be HTML so you can't quite get around that. Interesting thought though. Certainly, when you use components - the HTML is defined within the component so that saves on the actual static initial HTML pages have.
- Computeds are really funny to explain but many of you do this pretty good justice. They are at the end of the day, properties (i.e. computed properties) so you expect a specific value from them. But they're defined as functions that automatically run under certain conditions to compute that value. We never call computeds... Vue calls them when it detects it should recompute the property value. For those of you who are really into this, this idea actually has a native JS parallel. You can look up JS ACCESSORS, GETTERS and SETTERS to see the native concept/principle. More advanced but it's what allows this stuff we do in Vue to happen.
- You can definitely do loops in a loop if it's what you want. Usually something like that would happen if you have something like an array somewhere nested at some level in an array.
```html
<comp v-for="obj in list">
<p v-for="item in obj.subList">{{ item }}</p>
</comp>
```
```javascript
data() {
return {
list: [{
subList: ["a","b"]
},{
subList: ["c","d"]
}]
}
}
```