Vue: two params in url not loading correct route - javascript

Comunity
I have a list of bookings (component: BookingListItem), which I render in my component "BookingView". Now I want to show the booking details when I click on one of these booking items.
For this, I created a streched link, like that:
<router-link
:to="`patients/${this.user.id}/bookings/${booking.booking_id}`"
class="stretched-link"
></router-link>
I need the userid and the bookingid to make an api call from the ReadBookingView component (in this component the bookingdetails are displayed).
In my router.js file I defined the route like that:
{
path: "/patients/:userid/bookings/:bookingid",
name: "readbooking",
component: ReadBookingView,
},
But when I load my BookingView component the following warnings are showed:
There the userid and the bookingid are correct. But when I click on one of my booking items the following link is opened: http://URL:8081/4328
I hope y'all understand my explanation. Cause I don't understand why it's not loading correcty and I am very grateful for all your inputs.

Try
<router-link
:to="`/patients/${this.user.id}/bookings/${booking.booking_id}`"
class="stretched-link"
></router-link>

Related

How to send data from v-for to event handler in Vue?

I am having problems with sending the right data to the event handler of a subcomponent in my Vue component.
Here is my code:
<template>
<div>
<div v-for="item in [1, 2, 3]">
<div #click=test(item)>test</div>
<ConfirmModal v-if="showModal" #confirmed=test(item) />
<button v-on:click="showModal = true" ></button>
</div>
</div>
</template>
<script>
import ConfirmModal from 'ConfirmModal'
export default
{
components: {ConfirmModal},
data()
{
return {showModal: false}
},
methods:
{
test(item)
{
console.log(item);
this.showModal = false;
},
},
}
</script>
And here is the code for a subcomponent:
<template><div class="modal" #click.self="$emit('confirmed')">subtest</div></template>
So, basically, I here have an array of numbers and am using the v-for to iterate over an array.
For each item one test label, one subcomponent (containing a subtest label) and one button is created. When button is clicked, subcomponent is shown. When I click on the subcomponent (subtest label) it disappears.
div is a standard component which emmits #click events when it is clicked upon.
confirmModal is a very simple component which listens for #click events and redirects them into #confirmed events.
So, this code generates 3 times 3 items. When I click on any of the labels, test method is called which logs the value of the item.
When I click on any of the test labels, I get the correct value in the console, that is, 1 for the first item, 2 for the second item and so on.
But, when I click on any of the subtest labels, I allways get the 3, whichever link I clicked. (If I change the order of items in the array, then I allways get whichever item I put on the last place in the array).
I do not understand what is going on here, it is the same method called on the same way. Why is 3 allways logged in console when I click on the subtest label?
If you wonder what is class=modal in my subcomponent used for, I have no idea. This is a skeleton of two components in a very complex project consisting of thousands of files built on top of the Liferay, and there are more then ten files where is .modal defined in many directories. So I am not sure from which file does this particular component load this class. I did not throw it out of this skeleton code just because when I remove this class from the div in the subcomponent, everything works fine. I have no idea why. How can a class stop the correct data from being received? I do not get this.
I know that this bug may not be reproducable, because I did not provide the definition of the .modal style, but I posted it anyway, because I hope that you can see something else in the code what is wrong or propose another way how to execute the test method on #confirmed event.
I am using Vue 2.

Vue.js: Is there a way to make a buttons "v-if" reactive through watcher?

Basically, I have a userlist page with a bunch of other profiles including your own profile.
There is a button that only appears if you're on your own profile.
The problem is when I switch from some other profile to my own profile (Thus, paramater of the router is changing) that button should appear.
Vice-versa though works (my-profile -> another profile the button dissapears).
Now, the button only appears if I switch from another router (not from some other profile but instead a home page to my own profile for example).
On my Profile.vue
<v-btn
v-if= "isUserProfile()"
outline
large
fab
v-on="on"
color="indigo">
<v-icon>edit</v-icon>
</v-btn>
Using watcher in Profile.vue, looks out whenever the url/router param changes
watch: {
'$route.params.username': {
immediate: true,
handler (value) {
this.username = value
this.getId()
this.isUserProfile()
}
}
},
using the method,
isUserProfile () {
return (this.$store.state.route.params.username === this.$store.state.user.username)
},
So the button SHOULD appear everytime I switch to my own profile from another profile since it works when I switch from my profile to another profile.
For a gif example where my profile is "123123":
https://gyazo.com/cf47036bfb60cc6490c538e50a32db81
What I did here is switch the parameters on the url manually from going to my account, to another account back to my account.
(Button is there; good | is not there; good | button is still not there which should be there; bad.)
Okay, so the answer is simple and the modifications of making it a computed value was not necessary as I just checked (I think it is better practice to make it computed value though).
Answer:
Instead of v-if:isUserProfile, make it v-show:isUserProfile; where now the button changes to how what is to be accomplished.
I will now be reading https://v2.vuejs.org/v2/guide/conditional.html for further knowledge.

Vue.js v-for generated html block capturing collapse state with two way data binding

I'm trying to capture click action state (for collaps function) within html v-for generated block. To achieve this, I'm using declared data table, and it looks like state is being captured correctly. Below I'm ataching simplified v-for section, where I display state after click action. Displayed state is always false, even though after click, console.log shows table fields changes. Can someone please try to explain me why is that, and how to achieve what is expected here? I'm pretty new to vue, and must be doing something wrong...
<div v-for="address in userAddressData">
<a #click="expandControl(address.id)">
Address {{expandArea[address.id]}}
</a>
</div>
...
export default {
data () {
return {
userAddressData: '',
expandArea: [false,false,false]
}
},
methods: {
expandControl (id) {
this.expandArea[id] = !this.expandArea[id]
console.log(this.expandArea)
}
},
...
If I understood right, the problem you are having is that the template is not being updated according to the data, as we can see on this fiddle: https://jsfiddle.net/gen1kL3y/
This is issue is related to how Vue Reactivity works.
You can find another similar question here and I made a working JS fiddle for you here: https://jsfiddle.net/vz11zdjc/
Basically, instead of setting the value as this.expandArea[id] = !this.expandArea[id], you should (among other options) use Vue.set(this.expandArea, id, !this.expandArea[id])

Displaying a parent template in child template

I'm working to create a master view cordova/javascript application where a user a presented with a list of products, then depending on what they select, got to a tabbed based detail page about the product. Each tab will be generated depending on which product they pick. Along with the product specific information being loaded, I still want to keep a list a all the products in the view so that a user could switch products when ever they want. Here's an image to help better understand what I'm talking about. .
I tried to use ember.js to get this up and running but ran into a few issues. I can get the initial list of products generated and switch to the product specific details, but once I try to load the master list of products in my second template, everything breaks. I know about including two templates with an {{outlet}} in the parent template but I cant get this to have the child inherit the parent. Is this possible to do in ember or should I start looking at other frameworks like Anuglar? Any help is appreciated.
Displaying nested templates is actually where Ember has an advantage over other frameworks, in my opinion.
This should be really simple using nested resources. In your router, you can do something like
App.Router.map(function() {
this.resource('products', function() {
this.route('product', { path: '/product_id' });
});
});
Obviously, you'll have to fetch your data in each corresponding route. Something like
App.ProductsRoute = Ember.Route.extend({
model: function() {
this.store.find('product');
}
});
App.ProductsProductRoute = Ember.Route.extend({
model: function(params) {
this.store.find('product', params.product_id);
}
});
In your product template you'll need to include an {{outlet}} for all child routes to render into (ie, products.product).
For example
product.handlebars
{{#each}}
{{name}}
{{/each}}
{{outlet}}
products/product.handlebars
Product: {{id}}
Check out the resources section in the guides.
EDIT
If you want the master list to display differently between the products template and the products.product template, remove the master list from the products template and put it in the products.index and the products.product template.
Then specify that both the ProductsIndexController and the ProductsProductController needs its parent model. This will give both templates access to the products via controllers.products.
App.ProductsIndexController = Ember.ObjectController.extend({
needs: 'products',
products: Ember.computed.alias('controllers.products')
});
App.ProductsProductController = Ember.ObjectController.extend({
needs: 'products',
products: Ember.computed.alias('controllers.products')
});
See this jsbin and the associated guides.

Ember.js Routes and Back Button Issue

I'm having an issue with the template not rendering when I click the back button. From what I've read this is an issue because the parent template never goes away and the child routes should be rendered into the parent route. However, I want the users to have a clean page when they add records or edit records. I'm currently rendering the templates into named outlets on the main application template.
In this case, newrecord and editrecord should be rendered into form. However, I want the URL to be localhost/form/formID/newrecord so the user knows they're still in the form.
Question: What is the best way to achieve this? Do I have to change the routes as child resources or move them as higher level resources? Is there a better way to achieve what I want?
App.Router.map(function(){
this.resource('home', { path: '/' });
this.resource('form', { path: '/forms/:form_id' }, function() {
this.route('newrecord', { path: '/newrecord' });
this.route('editrecord', {path :'/editrecord' });
});
});
Template
<script type="text/x-handlebars" data-template-name="application">
{{ outlet }}
{{ outlet newrecord }}
{{ outlet editrecord }}
</script>
I found this was best answered here by Teddy Zenny.
Ember.js: Back button doesn't refresh index view when using nested routes

Categories

Resources