#CompositionAPI

Joe Steinbringjoe@jws.news
2024-07-23

Back in May, I showed How to get AI to tell you the flavor of the day at Kopp’s, and in the demo, I showed how you can populate a Chroma DB vector database using an API that I found on the Kopp’s website.  That is cool, but Kopp’s isn’t the only custard shop in the area.  Today, I want to look at how to get the flavor of the day for Culver’s programmatically, and then we are going to merge the data to start a unified custard dataset. Let’s start with the Kopps’s data.  For today’s demo, we are going to be using Vue.js and the Composition API (because I miss it more than I can express).

See the Pen
Kopp's Flavor Forecast
by Joe Steinbring (@steinbring)
on CodePen.

So, what is going on above?

I don’t know about you but that Bienenstichkuchen on the 27th sounds amazing to me.

For Culver’s, we can do something similar.  Using the API for getting the nearest locations, you can get what today’s “flavor of the day” is for that location.

See the Pen
Culver's "Flavor of the Day"
by Joe Steinbring (@steinbring)
on CodePen.

You might notice a problem with the Culver’s example, though.  They are using CORS to protect their API (as they should).  You can use a browser extension or a proxy to add CORS headers but this app won’t work by default.

So, how do we get it to work?  If we create a CloudFlare Workers script that gets the same data and then returns it to the user as JSON, we can simplify the data that is returned and add CORS headers.  Let’s see what the result looks like.

See the Pen
Culver's "Flavor of the Day" v2
by Joe Steinbring (@steinbring)
on CodePen.

So, what’s going on above?

  • onMounted(), the app is running fetchLocations() which makes an API call to https://culvers-fotd.joe.workers.dev and sets the value of locations.value to what comes back.
  • The template uses a simple v-for loop to iterate over the data.

The result is a list of Culver’s locations near Milwaukee and the flavor of the day at each one.

The next step is to merge the Kopp’s data with the Culver’s data but the datasets have a lot of differences.  The Kopp’s data is a flavor forecast while the Culver’s data only covers today’s flavors of the day.  Also, there is a different flavor of the day per Culver’s location where it is the same flavors at all three Kopp’s locations (Greenfield, Brookfield, and Glendale).

Let’s take a look at the unified listing of today’s flavors.

See the Pen
Culver's "Flavor of the Day" v2
by Joe Steinbring (@steinbring)
on CodePen.

So, what’s going on above?

  • The kopps variable holds the Kopp’s flavor data and the culvers variable holds the Culver’s flavor data.
  • fetchKopps() gets the Kopp’s data from the API and fetchCulvers() gets the Culver’s data from it’s API.
  • There is a combinedData computed property that combines the two datasets into one and then sorts it by what city the location is in.

So, what’s next?  Milwaukee has many more custard locations than those two (Gilles, Murfs, Kraverz, Kitt’s, etc).  For the most part, to get flavor data from those sites, you would need to screen scrap.  We recently looked at How to use AI to make web scraping easier, so we do have a mold for dealing with the issue.

Stay tuned for “Part Two”.

https://jws.news/2024/let-play-with-some-milwaukee-custard-data/

#API #CompositionAPI #CORS #JavaScript #JSON #VueJs

Joe Steinbringjoe@jws.news
2024-03-05

This past autumn, I started playing around with the Composition API, and at the October 2023 Hack and Tell, I put that knowledge into writing a “Job Tracker“.  The job tracker used Vuex and Firebase Authentication to log a user in using their Google credentials.  With const store = useStore() on your view, you can do something like Welcome, {{user.data.displayName}} but using this technique you can also use …

const LoginWithGoogle = async () => {
try {
await store.dispatch('loginWithGoogle')
router.push('/')
}
catch (err) {
error.value = err.message
}
}

… to kick off the authentication of the user.  I want to use it to finally finish the State Parks app but I also want to use Pinia instead of Vuex, I wanted the resulting app to be a PWA, and I wanted to allow the user to log in with more than just Google credentials.  So, this past week, I wrote my “Offline Vue Boilerplate“.  It is meant to be a starting point for the State Parks app and a few other apps that I have kicking around in my head.  I figured that this week, we should go over what I wrote.

Overview

The whole point of this “boilerplate” application was for it to be a common starting point for other applications that use Firebase for authentication and a NoSQL database.  It uses:

I was using a lot of this stack for work projects, also.  It is nice because Firebase is cheap and robust and you don’t need to write any server-side code.  Hosting of the front-end code is “cheap-as-chips”, also.  The Job Tracker is hosted using Firebase Hosting (which is free on the spark plan) and The Boilerplate App is hosted using Render, which is just as free.

Authentication

I am most proud of how I handled authentication with this app.  Here is what the Pinia store looks like:

From your view, you can access {{ user }} to get to the values that came out of the single sign-on (SSO) provider (the user’s name, email address, picture, etc).  For this app, I used Google and Microsoft but Firebase Authentication offers a lot of options beyond those two.

Adding Google is pretty easy (after all, Firebase is owned by Google) but adding Microsoft was more difficult. To get keys from Microsoft, you need to register your application with the Microsoft identity platform.  Unfortunately, the account that you use for that must be an Azure account with at least a Cloud Application Administrator privileges and it can not be a personal account.  The account must be associated with an Entra tenant.  This means that you need to spin up an Entra tenant to register the application and get the keys.

The third SSO provider that I was tempted to add was Apple but to do that, you need to enroll in the Apple Developer program, which is not cheap.

Firebase Cloud Firestore

I have become a big fan of Firebase Cloud Firestore over the years (at least for situations where a NoSQL database makes sense).  The paradigm that I started playing around with last year involved putting the Firebase CRUD functions in the composable.

Here is an example <script> block from the Job Tracker:

The author of the view doesn’t even need to know that Firebase Cloud Firestore is part of the stack.  You might wonder how security is handled.

Here is what the security rule looks like behind the job tracker:

The rule is structured so that any authenticated user can create a new record but users can only read, delete, or update if they created the record.

How I made it into a Progressive Web App (PWA)

This is the easiest bit of the whole process.  You just need to add vite-plugin-pwa to the dev dependencies and let it build your manifest.  You do need to supply icons for it to use but that’s easy enough.

The Next Steps

I am going to be using this as a stepping-stone to build 2-3 apps but you can look forward to a few deep-dive posts on the stack, also.

Have any questions, comments, etc?  Please feel free to drop a comment, below.

 

[ Cover photo by Barn Images on Unsplash ]

https://jws.news/2024/wrote-a-thing-with-vue-and-firebase/

#CompositionAPI #Firebase #pinia #StateParksApp #VueJs #vuex

R://i.ch.ard.exerichard@fedia.social
2024-01-31

Is there a quick and easy way of generating a default object based on a Typescript type / interface?

Long story short, to properly bind it in the application (Vue3 with Composition API and Typescript) and use it with -v-model i need to have the structure there otherwise something like: 'parent.child.itemvalue' will give undefined.

#vue3 #compositionAPI #typescript

Joe Steinbringjoe@jws.news
2023-11-16

This past month, I visited the local Hack & Tell to write a web app that uses Vue.js‘s Composition API. I have written 41 posts involving Vue on this blog but the Composition API is new here.  If you are the “eat your dessert first” type, you can check out the result at https://joes-job-tracker.web.app.  I want to spend this article reviewing the composition API, though.

Let me start by explaining what the Composition API is.  The Composition API is a collection of APIs that enable the creation of Vue components by utilizing imported functions, as opposed to the traditional method of declaring options. This term encompasses the Reactivity API, Lifecycle Hooks, and Dependency Injection. The Composition API is an integrated feature within both Vue 3 and Vue 2.7.  It is a bit of a departure from the traditional Vue 2 way of writing code but Vue 2 applications can use the officially maintained @vue/composition-api plugin.

So, what do the differences actually look like?  Let’s take a look at the example of an app that tracks the location of the user’s mouse cursor.  The first version uses the Vue 2 method where you declare options and the second version does the same thing but uses imported functions.

See the Pen
Track Mouse - Vue 2
by Joe Steinbring (@steinbring)
on CodePen.

See the Pen
Track Mouse - Composition API
by Joe Steinbring (@steinbring)
on CodePen.

 

So, what are the differences between the two?  Let’s compare and contrast.

Vue 2Composition APInew Vue({
el: '#app',
data: {
mouseX: 0,
mouseY: 0,
},
methods: {
trackMouse(event) {
this.mouseX = event.clientX;
this.mouseY = event.clientY;
},
},
mounted() {
// Attach an event listener to track mouse movement
window.addEventListener('mousemove', this.trackMouse);
},
beforeDestroy() {
// Clean up the event listener to prevent memory leaks
window.removeEventListener('mousemove', this.trackMouse);
},
});import { createApp, ref, onMounted, onBeforeUnmount } from 'vue'

createApp({
setup() {
const mouseX = ref(0);
const mouseY = ref(0);

const trackMouse = (event) => {
mouseX.value = event.clientX;
mouseY.value = event.clientY;
};

onMounted(() => {
window.addEventListener('mousemove', trackMouse);
});

onBeforeUnmount(() => {
window.removeEventListener('mousemove', trackMouse);
});

return {
mouseX,
mouseY,
};
},
}).mount('#app')

In the Vue 3 Composition API version, the setup function is used to defines the component’s logic, and it uses reactive references (ref) to manage the state.  Event handling is encapsulated within the onMounted and onBeforeUnmount lifecycle hooks.  Vue 3 promotes a more modular and declarative approach.  In the Vue 2 version, the code uses the Options API with a more traditional structure, relying on data, methods, and lifecycle hooks like mounted and beforeDestroy.  Vue 3’s Composition API simplifies the code structure and encourages better organization and reusability of logic.

If you are anything like me, your first question is what reactive references are.  Vue 2 doesn’t have a built-in equivalent to the ref and reactive features found in Vue 3. When you use a ref in a template, modifying its value triggers Vue’s automatic detection of the change, leading to a corresponding update of the DOM.  This is made possible with a dependency-tracking based reactivity system. During the initial rendering of a component, Vue meticulously monitors and records every ref used in the process. Subsequently, when a ref undergoes a mutation, it initiates a re-render for the components that are observing it.

Here are the Vue 2 and the Composition API versions of the same application:

See the Pen
Vue 2 Equivelent to composition API Ref
by Joe Steinbring (@steinbring)
on CodePen.

See the Pen
Track Mouse - Composition API
by Joe Steinbring (@steinbring)
on CodePen.

Vue 3’s reactivity system is more efficient and performs better than Vue 2.  This can result in better overall performance, especially in applications with complex reactivity requirements.  It also reduces the use of magic keywords like this, which can be a source of confusion in Vue 2.

 

Here are the two versions, side by side:

VUE 2COMPOSITION APInew Vue({
el: ‘#app’,
data: {
myValue: 42,
},
methods: {
updateMyValue() {
this.myValue = 69; // Update the value
},
},
});import { createApp, ref, onMounted } from ‘vue’;

const app = createApp({
setup() {
const myValue = ref(42);

const updateMyValue = () => {
myValue.value = 69; // Update the value
};

return { myValue, updateMyValue };
}
});

app.mount(‘#app’);

 

Another thing that the Composition API brings to the table is composables. Vue composables are special functions that leverage the Composition API to create reactive and reusable logic. They serve as external functions, abstracting reactive states and functionalities for use in multiple components. These composables, also known as composition functions, streamline the process of sharing logic across different parts of an application.

In functionality, composables are akin to Vue 2’s mixins found in the Options API and resemble the concept of Hooks in React.

I am going to wait for a future post to cover composables, though.

https://jws.news/2023/learning-the-composition-api/

#Composables #CompositionAPI #Firebase #Hackathon #VueJs

A group of people who are seated and watching a speaker at the front of a room
Shini92 :ablobblewobble:Shini92@mas.to
2023-06-16

I released github.com/Shinigami92/vite-pl and now support #esm aside from #cjs
But it only works up to #typescript v4.9 ⚠️

Luckily #vue3 has now much better #typescript support for #watch via #compositionapi, so you might not need it anyway anymore

Please open issues if you are running into issues

Robert Schäferroschaefer
2020-12-04

Philipp gives a about the in 3. Next up is with and with -shield. In the last 30 minutes I mess up my own live demo about in 🙈.

peertube.social/videos/watch/4 and youtu.be/ZJrjOyp8anc

Client Info

Server: https://mastodon.social
Version: 2025.04
Repository: https://github.com/cyevgeniy/lmst