How to Reload to same Page while sending a parameter? - javascript

I need to reload the page whenever different buttons are pressed, while sending a String to the same page so that on created() it takes that String and sends an HTTP Get into my Database.
Currently I have the following:
export default {
data(){
return{
events: [],
formData:{
sportType: 'Ténis'
}
}
},
created(){
//Do something here to get the value sent from the reloading
axios.get(`http://localhost:8001/evento`, {headers: {sportType: this.formData.sportType}})
.then((response)=>{
this.events = response.events
},(error) =>{
console.log(error);
});
},
pickSport(item){
}
The function pickSport() is called whenever the buttons are pressed and each sends a value to this function that is a String. The idea now is to be able to reload the page when this function is called, while sending this item to the reloaded page, so I can update the value of sportType. I tried:
pickDesporto(item){
this.$router.push({
path: '/betting',
params: item
});
}
But with no success, since it keeps giving me a NavigationDuplicated error. How can I solve this?

They are many way to do this. You may want to use Watch: {} to keep track of certain parameter. It will be trigger once the parameter change and you can re-render the same page with new parameter.
There is also a way called key-binding but it need to bind the key to the component. I personally suggest this one because it will be easy to understand.

Related

Vue router change query on current route

I have a URL I'm appending attribute parameters to using this code:
this.$router.push({ query: Object.assign({}, this.$route.query, { attributes: this.encodedAttributes() }) });
When I call that method the second time, the parameters get added again. But I want it to update rather than adding another time if there are already attribute parameters. Any help is highly appreciated.
(Referring to the code link in comments) Putting a stringified array into a query param will not convert it to query params. It's also part of a nested object which also wouldn't work.
Make dynamic_fields an object:
data() {
return {
dynamic_fields: {},
};
},
Remove encodedAttributes and change search:
search() {
this.$router.push({ query: this.dynamic_fields })
.catch(failure => false);
}
.catch on $router push prevents the navigation failure error.
Here is an updated sandbox

Submitting a post that belongs to current user - how to define the relation on client-side in Vue?

Im building an app using Node.js, specifically Express server-side and Vue client-side, with SQLite + Sequelize for managing the database.
Part of the functionality is that a user can make a post. This is currently possible but I needed to implement a relation so a post can be associated with the author.
I did this server-side in sequelize and all seems to be well on that end as the table columns all look correct with foreign key and references etc.
So now I need to somehow presumably set the current UserId for the post before it gets submitted. Here is the script element for the Vue component which is to be used as the interface to make posts.
<script>
import PostService from '#/services/PostService'
export default {
data () {
return {
post: {
title: null,
body: null
}
}
},
methods: {
async submit () {
try {
await PostService.post(this.post)
} catch (err) {
console.log(err.response.data.error)
}
}
}
}
</script>
I'm using Vuex to manage the state, where the 'user' object response from the database upon login is stored as simply user in my store.
So I was guessing all I had to do was the following to access the user:
post: {
title: null,
body: null
UserId: this.$store.state.user.id
}
The problem is any time I insert this line, the component stops working in some way. Doing as above stops the component displaying at all. So I tried setting it to null as default, then instead doing this inside my submit method:
this.post.UserId = this.$store.state.user.id
If I do this, the component displays but the submit method no longer runs; I also tried both these methods without the .id just incase, no difference.
I then tried removed from the data model completely, after reading that sequelize may be generating a setUser method for my post model. So tried the following in submit method before sending the post:
this.post.setUser(this.$store.state.user)
... again the method stops running. Again, even if adding .id.
Without trying to set any ID at all, everything works until the server returns an error that 'Post.UserID cannot be null', and everything worked perfectly before I implemented the relation.
I haven't really found anything useful beyond what I already tried from doing a few searches. Can anyone help out? I'm totally new to Node.
I have accessed other parts of the state such as isUserLoggedIn, and it all works fine and no crashes occur in those cases.
I just managed to get it working correctly, I'm not sure why it suddenly started working as I am sure I had tried this before, but I solved it by doing the following within my component's script element:
<script>
import PostService from '#/services/PostService'
export default {
data () {
return {
post: {
title: null,
body: null,
UserId: null
}
}
},
methods: {
async submit () {
this.post.UserId = this.$store.state.user.id
try {
await PostService.post(this.post)
} catch (err) {
console.log(err.response.data.error)
}
}
}
}
</script>
Posts now create and display as normal. If anyone knows anything I'm technicially not doing right in any of my approach though please let me know, as I am still learning Node, Express and Vue.

Vue Router, construct a route

I am making a data table with a search field in my application and I would like to implement the following behaviour:
When a user types a research, the URL gets updated. If a user clicks
on a link and hit "back" from his navigator, he gets back to his last
search.
For the moment, I am doing the following thing:
export default {
data () {
return {
search: ''
}
},
watch: {
search (value) {
this.$router.replace('/products?search=' + value)
}
}
}
As you can see, I am using the replace function of the router. That allows me to make it work. And it's better than the push method because if a user hits "back" during a search, he will go to his last page and not last research, and that's exactly what I want.
However, I don't like how I hard write the URL.
I would love to make something like that:
watch: {
search (value) {
let route = new Route(this.$route)
route.query.search = value
this.$router.replace(route.getPath())
}
}
Because, let's imagine that the user has other parameters like pagination or something like that, they would be erased. I would like a method that takes my actual url and add/replace a query string parameter.
Is this something I can achieve with Vue Router or do I need to do something else: Other package / Vanilla JS?
Why not just use the object location parameter $router.replace? Eg:
watch: {
search (value) {
this.$router.replace({ path: 'products', query: { search: value }})
}
}

In a React.js app, an API calls fails in the store, how do I transmit that back to the view?

https://cask.scotch.io/2014/10/V70cSEC.png
^ According to this flow, I have to make a change in the store, which is then picked up by the view.
More specifically, I am trying to delete a user, but when the store gets an error from the DB, I want to show a modal saying the error occurred. Would the right way of transmitting the message be done through the store variables and then picked up in the view on the getStateFromFlux method?
userStore = {
initialize: function(options) {
// other variables
this.userDeletionError = false;
},
deleteUser: function(payload) {
Axios.delete(DBURL)
.then((response) => {
// succeeds
})
.catch((error) => {
// other error handling
this.userDeletionError = true;
});
}
}
If I understand well you are using an ajax call in a store, this is an antipattern. The right way to do is make the call in the action file then transmit it in the store.
To answer your question the flux-pattern should look like that (not sure if it match 100% your use case).
View => User want to delete a 'user', he clicks on the delete button
View triggers an action.
Action triggers an ajax call 'delete this user'
Action receives the answer and transmit it to the store (here you are using the react dispatcher , example below:
MyAjaxCall.then(function(answer) {
Dispatcher.handleViewAction({
actionType: Constants.ActionTypes.DELETE_USER,
result: answer
});
});
5.Your store is catching the ajax answer still through the dispatcher (example below:
MyStore.dispatcherIndex = Dispatcher.register(function(payload) {
var action = payload.action;
var result;
switch(action.actionType) {
case Constants.ActionTypes.USER_DELETE:
registerAnswer(action.result);
MyStore.emitChange();
break;
}
return true;
});
You can see that your store will trigger registerAnswer(), in this function you can check if the ajaxcall has been executed (I mean is the user deleted or not) and accordingly build the object. Here there is two way to tell your view about the answer status 1. you build an dataAnswer object with a field message for example and then your view can check it 2. you emit a special event.
I prefer the first way if find it more generic.
Store emitChange and your view catch the event (example below:
componentDidMount: function() {
MyStore.addChangeListener(address, this._onDeleteUser;
},
Then your view check the 'message' field you filled in the store accordingly to the answer and you can render whatever is appropriate.
I hope it's clear. Here is an example of store in case you need it. https://facebook.github.io/flux/docs/todo-list.html#creating-stores
To resume, your approach is good except doing the ajax call in the store. Don't do that it's really bad.
Hope it helps

Meteor: getting route param on page loading

Here is my issue:
I am trying to make an API call when loading my page to load one entity, saving few of this entity attributes into the session - so I basically make one call, and use the attributes whenever I need them.
But when I try to get the id param from the Route, the Router.current() at the beginning of my script, it is null.
On the other hand, when I call the same Router.current() on a helper, I can get my param.
Any idea what is wrong / how can I get this param before calling my helpers ?
Here is my html where I will be using one of this attribute:
<input type="text" name="name" id="addCampaignInputName" value="{{currentCampaignName}}" placeholder="New Campaign Name">
And the JS:
if (Meteor.isClient)
{
$(function () {
console.log( Router.current()); ==>> NULL
if( Router.current() !== null) {
Meteor.call("getApiCampaignsById", Router.current().params.id, function(error, results) {
Session.set('currentCampaignDetailsName', results.data.name);
Session.set('currentCampaignDetailsTrackingMethod', results.data.tracking_method_id);
Session.set('currentCampaignDetailsCampaignTypeId', results.data.campaign_type_id);
});
}
});
Template.addCampaign.helpers({
currentCampaignName: function() {
console.log( Router.current()); ===>> DUMP DATA
return Session.get('currentCampaignDetailsName');
},
});
}
That's because template helpers are always run inside reactive computation, and Router.current() happens to be a reactive data source, so when it's ready the helper will rerun with the correct value.
Since you're using iron:router, you could use an onBeforeAction hook, because they can be tied to a specific route and are executed when route parameters are available (use this.params).
Router.route("/my-route", {
name: "myRoute",
onBeforeAction: function(){
Meteor.call("getApiCampaignsById", this.params.id, function(error, results) {
Session.set('currentCampaignDetailsName', results.data.name);
Session.set('currentCampaignDetailsTrackingMethod', results.data.tracking_method_id);
Session.set('currentCampaignDetailsCampaignTypeId', results.data.campaign_type_id);
});
//
this.next();
}
});
You should load your template only once its subscriptions/parameters are ready. Look at my answer here, maybe it will solve your problem (especially the part where you attach your parameters to your template data object.)
Your first function is likely running on the page before anything else has loaded, and it doesn't know what Router is. The best way to set these before the template helpers are loaded is to use iron-router's onBeforeAction hook:
Router.route('/', {
name: 'home',
onBeforeAction: function() {
//set your session variables here
this.next();
}
});
This way, the router should load the page with your session vars already set.

Categories