Vue recognize text pattern and replace by href to correct resource - vue.js

I'm working on a project where I keep a log of key actions by users. For example a log entry is made when a user logs in to the application. I use a Laravel API as backend that takes care of the logging the event in the database and takes care of retrieving log entries to be displayed in the application. An example of a log entry returned for display is the following:
{{user|123|"John Doe"}} logged in at 2020-01-03 11:00:05
Now, I'd like Vue to automatically recognize that this should be replaced by the following:
<router-link to="/user/123">John Doe</router-link> logged in at 2020-01-03 11:00:05
So it automatically becomes a clickable link that navigates to the user profile in this case.
Does Vue offer any such functionality? Any ideas on how to approach this?
Thanks!

Yes, you can bind to to a computed property that will build the path string or data property (then you need to save the builded path in a data section when receving your response):
Template:
<router-link :to="path">{{userName}}</router-link>
script:
export default {
data() {
return {
path: '',
userName: ''
}
},
// OR
computed: {
path() {
<build your path from entry variable>
return <your builded path>
},
userName() {
<extract your user name>
return <extracted user name>
}
}
}

<div v-for="user in users" :key="user.id">
<router-link :to="user.path">{{user.name}}</router-link>
logged in at {{ user.loginTime }}
</div>
I think I will use a v-for to do this, I am wondering what data you got from your Ajax api ?

Related

how to use dynamic routing in vuejs

this is my json object ,i'm trying to access jackets in my url
{
"_id": "6316f215fd9c107baa1bc160"
"type": "Jackets",
}
this is my router component to get product by id
{
path: "/product/:id",
},
if i want to get my product information by id
<router-link :to="`/product/${product._id}`">
<div
class="bg-image hover-zoom ripple"
data-mdb-ripple-color="light"
>
<img
src="../../assets/pexels-baskin-creative-studios-1766838.jpg"
class="card-img-top"
/>
</div>
</router-link>
this is my url
http://localhost:8082/product/6316f215fd9c107baa1bc160
i get jackets in my template after clicking the router-link
{{product.type}}
how can i get add jackets in my url to something like this
http://localhost:8082/product/jackets
and still display the json details in my template component
As per my understanding, You want to slightly change the current route path without refreshing/reloading the page. If Yes, You can achieve that by using history.replaceState() API.
history.replaceState({}, '', this.$route.path + '/' + <your product name>)

Load a different page in nuxt at runtime based on the parameters in the route

We have a scenario in which a different page is required to be loaded based on whether parts of the route has parameters that are valid and that can be determined at run-time.
Consider the following example:
Request to http://example.com/param1/param2
If param1 is a valid product identifier (can be determined by an API call to another service) the product page loads or its considered a category and Category Page is loaded.
Considering Nuxt uses static routes mostly and the list of products are dynamic, is there a hook where you can execute custom code to load a different page ?
Cant you create _product page
like described in nuxt docs:
https://nuxtjs.org/guide/routing/#dynamic-routes
And in your code make something like:
<template>
<div>
<nuxt-child />
</div>
</template>
<script>
export default {
asyncData({route, params, redirect}) {
//use route
console.log(route.params.slug)
//directly use params
console.log(params.slug)
redirect(`/`);
},
};
</script>
or use mounted() hook if you are creating SPA

vue-apollo: GraphQL queries only run when using <ApolloQuery> tags. Never works in script code. this.$apollo.queries is empty

I know I'm probably missing something really super basic here, I'm trying to run a graphql query with vue-apollo... if I use tags, it works fine
If I try to run queries from inside my code, like in the basic examples in the docs (links below) then nothing happens. The server never receives any request, and this.$apollo.queries is empty.)
Basic examples from the docs:
https://akryum.github.io/vue-apollo/guide/apollo/#queries
https://vue-apollo.netlify.com/guide/apollo/queries.html#simple-query
I've defined the query in the "apollo" property/object... how do I actually execute it when the page loads? Note that I'm using typescript, which is why it's using a "get apollo()" method.
Here's my code...
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
export default class List extends Vue {
myQueryName='my default value';
get apollo() {
return {
myQueryName: {
query: require('../graphql/listMeta.graphql'),
// prefetch: true <-- tried with and without this
}
}
}
}
</script>
<template>
<div>
<!-- THIS DOESN"T WORK ... -->
queries are: {{this.$apollo.queries}} <!-- THIS JUST SHOWS AN EMPTY OBJECT: {} -->
<hr>
myQueryName value is: {{myQueryName}} <!-- THIS JUST SHOWS "my default value" -->
<hr>
<!--
THIS DOES WORK...
<ApolloQuery :query="this.apollo.myQueryName.query" >
<template slot-scope="{ result: { loading, error, data } }"></template>
</ApolloQuery>
-->
</div>
</template>
Note that this.$apollo.queries is empty in the template, probably a clue... but still no idea why its empty. From the docs and examples I've seen it should be populated from my get apollo data method.
Looks basically the same as https://github.com/OniVe/vue-apollo-typescript-example/blob/master/pages/index.vue as far as I can tell, I don't know what the difference is.
I've tried rebuilding the project from scratch multiple times (with and without nuxt), over teh course of months and many different versions of vue/nuxt/apollo/vue-apollo... the queries never run (from memory) unless I use tags.
What am I missing?
You are missing #Component decorator, it is needed to set initial properties of Vue component, so vue-apollo can detect it when component created and make a smartquery property.
import { Component, Vue } from 'vue-property-decorator'
import listMetaDocument from '../graphql/listMeta.gql'
#Component({
name: 'List',
apollo: {
listMeta: {
query: listMetaDocument
},
},
})
export default class List extends Vue { }

Dynamic routing in Vue.js, showing `this.$route.params.id` in html

I have a page that uses dynamic routing.
I have a "jobs" page that lists all jobs. One you click one job, it gives you the detail of that one job.
Jobs HTML page uses the following (snippets excludes ul/li tags):
<vue-panel v-for="job in jobs" v-if="filterJob(job)" v-bind:key="job.id">
Job: {{job.title}}<br>
Description: {{job.description}}<br>
Salary: ${{job.salary}}<br>
Date Posted: {{job.datePosted}}<br>
<router-link :to="`/job/${job.id}`">Learn More</router-link>
Clicking learn more leads to the correct job page. But how do I dynamically show just that specific job?
In the Job page, within the script I have:
created() {
console.log(this.$route.params.id); // prints value of :id
},
Via console log I see that it has access to the correct job page. But it is not dynamically showing that one job on the page. What needs to be in the HTML to access a specific job?
HTML of job page, as of now (excludes the ul/li tags):
<vue-panel v-bind:key="job.id">
Job: {{job.title}}<br>
Description: {{job.description}}<br>
Salary: ${{job.salary}}<br>
Date Posted: {{job.datePosted}}<br>
I built a similiar project and did the following.
router.js:
{
path: '/jobs/:id',
name: 'JobSingle',
component: JobSingle
}
jobs.vue
<router-link :to="{name:'JobSingle', params:{id:job._id}}">
{{ job.title }}
</router-link>
For more question you can have a look at my project here: github.com/markusdanek/t2w-vue
If you want to access by HTML you have to not bind key.
mounted(){
document.getElementById("H1").setAttribute("key", this.$route.params.id);
console.log('alex : ',document.getElementById("H1"));
}
When you use it by vue, you can't do by v-bind as type:
This works:
<div :type="$route.params.id">Verticals Statistics</div>
This don't work:
<div :key="$route.params.id">Verticals Statistics</div>
So you'll have to trick for passing a :key by vue, or as you did, with :
<div v-for='id in [$route.params.id]' :key="id">Verticals Statistics</div>
But it will not apear in HTML code.
You have to put an id on each and create the key attribute in the mounted part.

How to use route options (replace=true) in a link generated with route-href?

Is it possible for a route-href generated link to have the replace=true option when pushState is enabled?
I have tried:
<a route-href="route: user/details; options.bind: {replace: true}">Link</a>
and it does not work. There is no error and the view changes but after clicking the link a new item in the browser history appears (and it should not).
I don't believe so. The route-href generates an href attribute containing the url to the specified route. To navigate to a route using replace: true you'd have to create a method in your view-model and call this method using a click event. Something like this:
ViewModel
goToRoute() {
this.route.navigateToRoute('myRoute', { id:'someId' }, { replace: true });
}
View
<a click.delegate="goToRoute()"></a>