i have following problem:
In the title you can read my error message.
I have in my layouts/default.vue an code that checks if i have an cookie stored in this browser.
If its the case, i get the data from the cookie and store it in my store/index.vue
if (getCookie("jwt") != null) {
this.$store.commit("storageToken", getCookie("jwt"));
}
And in my store i got this code:
storageToken: function(state, payload) {
state.token = payload;
state.loggedIn = true;
},
The problem here is now the state.loggedIn. If i set it from false to true, it shows me the error because have in layouts/default.vue an nuxt-link like this:
<nuxt-link v-if="$store.state.loggedIn" class="loginbtn" to="dashboard">Dashboard</nuxt-link>
If i remove my nuxt-link tag, the loggedIn value gets changed without problems.
I found a way to make it work, if i wrap it in client-only.
<client-only>
<nuxt-link v-if="$store.state.loggedIn" class="loginbtn" to="dashboard">Dashboard</nuxt-link>
</client-only>
It works now, but the problem i have now is a SEO problem. My intern links arent visible for the google crawler now. When i analyze my website it says "could not find any intern links"
So how do i make this work again? I found no answer not here also not on google
Related
I have a interesting problem,
I have a flexdashboard that uses firebase auth to log into the app. Part of the login process assigns a reactive value rv$userName which by default is set to NULL.
Once the user successfully logs in, I then assign the reactive value to a value. But now I am trying to create a simple redirect in case the user access part of the app while not logged in.
I am putting this code on the Rmd file above the page that is being rendered and required to be logged in:
library(flexdashboard)
library(shiny)
library(shinyWidgets)
library(shinydashboard)
library(shinyjs)
renderUI({
observe({
if(is.null(rv$userName)){
tags$script(JS("window.location.href = '/SmartAlpha_Screener.Rmd';"))
}
})
})
The result is an error: Error: cannot coerce type 'environment' to vector of type 'character'
the location /SmartAlpha_Screener.Rmd is the location of the top of the app and is not the issue as I use it in other js on the app.
Ugh, I am stuck.. anyone know what I am doing wrong?
Cheers,
Sody
Edit: I guess the question I am asking is there a easy way to run JS when a new flexdashboard page is loaded with a if statement? I wanted to avoid running the if statement in JS and leave it on the shiny side, for security purposes.
Okay got it working,
First, I added some JS to handle the redirect.
Shiny.addCustomMessageHandler('myRedirect', function(u) {
if (!u) {
window.location.href = '/SmartAlpha_Screener.Rmd';
}
});
After that I had to wrap the code in renderUI to keep the code on that page only and not run across the entire site. From there I used shiny's useful session$sendCustomMessage to pass a boolean to JS function. Now if someone access the app using a url and is not logged in, it simple redirects them to the log in page.
renderUI({
if(is.null(rv$userName)) {
observe({
session$sendCustomMessage("myRedirect", FALSE)
invalidateLater(1000*60)
})
}
})
and BAM, if you go to a page while not logged in you are directed to the log in page.
Cheers,
if you have a better option or way of handling this please share!!
I'm struggling to initialize my Vuex store with the account details of the logged in user from localStorage.
I've been through as many examples as I can of Auth using Nuxt, and none of them demonstrate how on the client side to pull an authToken from localStorage to re-use with subsequent API requests when the user refreshes the page or navigates to the App
Disclaimer: I'm not using Nuxt in SSR (this might affect your answer).
What is annoying is that I can actually load from localStorage and initialize my state but then it gets overwritten. I'll show you what I mean with this small code example:
buildInitialState () {
if (!process.server) {
// Query the localStorage and return accessToken, refreshToken and account details
return {accessToken: <valid-string>, refreshToken: <valid-string>, account: <valid-json-blob>}
} else {
// Return "empty map", we use the string "INVALID" for demonstration purposes.
return {accessToken: "INVALID", refreshToken: "INVALID", account: "INVALID"}
}
}
export const state = () => buildInitialState()
If I put a breakpoint on buildInitialState I can see that I correctly initialize the state with the value of localStorage, i.e. I get the accessToken and refreshToken, etc.. back.
All seems well.
But then .....in another part of the program I'm using Axois to send requests, and I use an axios interceptor to decorate the request with the accessToken. To do this I have to stick it into a plugin to get access to the store.
Something like so:
export default ({ app, store }) => {
axios.interceptors.request.use((config) => {
const accessToken = _.get(store.state, ['account', 'accessToken'])
if (accessToken) {
config.headers.common['x-auth-token'] = accessToken
}
return config
}, (error) => Promise.reject(error))
}
Here the store is closed over in the arrow function supplied to axios so when I go to send the request it sees if there is a valid accessToken, and if so then use it.
BUT, and here's the kicker, when a request is made, I look at the store.state.account.accessToken and low and behold its been reinitialized back to the value of "INVALID".
What? Que?
It's almost like the store was reinitialized behind the scenes? Or somehow the state in the plugin is "server side state"?? because if I try and log buildInitialState I don't get any messages indicating that the path that produced a map with INVALID is being run.
Basically, I don't thoroughly understand the initialization pathway Nuxt is taking here at all.
If any Nuxt masters could help me out understand this a bit more that would be great, it's turning into a bit of a show stopper for me.
Essentially! All I want to be able to do is save the user so that when they refresh their page we can keep on running without forcing them to re-login again....I thought that would be simple.
Thanks and regards, Jason.
I've solved this with a bit of experimentation and comments from other posters around what is called SSR and SPA.
Firstly, this https://github.com/nuxt/nuxt.js/issues/1500 thread really helped me and the final comment from #jsonberry steered my mind in the right direction, away from fetch and asyncData.
I finally had a bit more of an understanding of how NUXT.js was separating SSR and SPA calls.
I then tried #robyedlin suggestion of putting localStorage initialization in the created() method for my main layout/default.vue page.
While I made progress with that suggestion it turns out created() is also called SSR and I was still trying to initialize my store from credentials that weren't accessible.
Finally, moving the initialization to mounted() did the trick!
So in summary:
My account store is left alone, I don't try and initialize it when it is created (it's just overwritten at some point when the SSR stuff runs)
On mounted() in layout/defualt.vue I read from localStorage and initialize the account store so I can start making API requests with the appropriate accessToken.
That seems to have done the trick.
I need to show active visitors on my website based on Page title.
Example : If the user is Contact Us page, then onlycount of active visitors on 'Contact us' page is to be shown instead of entire site.
I am following Embed API Third Party Visualizations
I tried the following code but it is not working
var activeUsers = new gapi.analytics.ext.ActiveUsers({
container: 'active-users-container',
pollingInterval: 5,
query: {
filters:'ga:pageTitle==Contact'
}
});
Please help me to resolve this issue.
As I mentioned in the Github issue opened about this same question, what you're asking to do is not possible with the current ActiveUsers Embed API component (it's just for demo purposes, it's not intended to be a full-featured Real Time query component).
However, this component could easily be modified to support your use case. You'd just have to update the lines that make the API request to add your query parameters.
Here is the relevant line of code that makes the request:
gapi.client.analytics.data.realtime
.get({ids: options.ids, metrics: 'rt:activeUsers'})
.then(function(response) {
// ... do something with the response
});
To add your filter, you'd just have to change that line to something like this:
gapi.client.analytics.data.realtime
.get({
ids: options.ids,
metrics: 'rt:activeUsers',
filters: 'ga:pageTitle==Contact'
})
.then(function(response) {
// ... do something with the response
});
Of course, you'd probably rather refactor the component to accept an options object (as you show in your question), so you don't have to hard code your query, but I'll leave it up to you to make that code change.
To point you in the right direction, you should read the Embed API guide: Creating Custom Components. You'll probably also need to reference the Shared Component Reference to see the methods all components can call.
I tried this Show active visitors after filtering
it worked.
I'm new to Meteor so I've been playing around and now I'm stuck with this problem.
I'm using React Router to try to show a theme based in the URL /(:userId). If there's no userId inserted into the URL it should show the current user's theme and If there's no current user it should show a default theme.
It's working randomly. Sometimes I get correct theme, sometime it throws undefined when reading themeColor even though the data is there. I can see with console.log that it always get the right Id, but still findOne can throws undefined. It specially happens when I change the URL (/xyz) and go back to the default one (/).
I verified with the console that userId is the actual owner of themeColor and themeTextColor.
I'm using React, React-router, autopublish. I removed insecure.
getMeteorData() {
var currentViewedPageId = this.props.params.userId? this.props.params.userId:(Meteor.userId()?Meteor.userId():false);
console.log(currentViewedPageId); //Allways right
console.log(Personalization.findOne({owner: currentViewedPageId}).themeColor); //Sometimes undefined, sometimes not
if(currentViewedPageId)
{
return {
currentUser: Meteor.user(),
themeColor: Personalization.findOne({owner: currentViewedPageId}).themeColor,
themeTextColor: Personalization.findOne({owner: currentViewedPageId}).themeTextColor
};
}
return {
currentUser: Meteor.user()
}
},
Since the code is working sometime. There can be some test data which doesn't match the schema. So test all data in the collection.
I am creating an error hook in my Ember.js app to redirect you to the auth service if you are not allowed to view certain content (in other words, if the server returns a 401).
It looks like this:
Ember.Route = Ember.Route.extend({
error: function(error, transition){
if (error.status === 401) {
window.location.replace("https://auth.censored.co.za");
}
}
Our auth api works as follows: If you send it a parameter called target (which is a url), it will redirect you back to that target url after you've logged in.
So I want to somehow get the URL of the route the Ember app was trying to transition to.
Then my code will end up something like this
Ember.Route = Ember.Route.extend({
error: function(error, transition){
if (error.status === 401) {
var target = // Your answer here
window.location.replace("https://auth.censored.co.za?target=" + encodeURIComponent(target));
}
}
I came across a need for this too, and resorted to using some internal APIs. In my case, I wanted to reload the whole app so that if you're switching users there's not data left over from the other user. When I reload the app, I want to put the user at the URL they tried to transition to, but for which they had insufficient privileges. After they authenticate (and thus have the bearer token in localstorage) I wanted to use window.location.replace(url) to get a clean copy of the whole app with the user at the URL implied by the Ember Transition object. But the question was, how do I go from a Transition object to a URL? Here is my solution, which uses the generate method which is a private API of the router:
let paramsCount = 0;
let params = {};
let args = [transition.targetName];
// Iterate over route segments
for (let key1 in transition.params) {
if (transition.params.hasOwnProperty(key1)) {
let segment = transition.params[key1];
// Iterate over the params for the route segment.
for (let key2 in segment) {
if (segment.hasOwnProperty(key2)) {
if (segment[key2] != null) {
params[key2] = segment[key2];
paramsCount++;
}
}
}
}
}
if (paramsCount > 0) {
args.push(params);
}
let url = router.generate.apply(router, args);
You'll need to get the router somehow either with a container lookup or some other means. I got it by injecting the -routing service which is documented as an API that might be publically exposed in the future (used by link-to), and which happens to have the router as a property.
While messy, perhaps you might find this helpful.
I was able to use transition.intent.url to accomplish exactly this. I'm not sure if this is private or not -- relevant discussion: https://discuss.emberjs.com/t/getting-url-from-ember-router-transition-for-sso-login/7079/2.
After spending several hours searching for an answer to this question and using the Chrome debugger to try and reverse engineer the Ember 2.5 code, my conclusion is that what you are looking for is not possible at the present time.
For people who don't understand why someone wants to do this, the case arises when authentication (e.g the login page) is separated from the application. This is necessary if there is a requirement not to deliver any content (including the application itself) to the user if the user is not authenticated. In other words, the login page cannot be part of the application because the user is not allowed to access the application before logging in.
PS: I realize this is not a solution to the user's question and probably more suitable as a comment. However, I can't post comments.
Kevins answer is the most correct one, I came to a similar solution. Basically I found how the link-to component was populating the href attribute and used the same sort of code.
In your object inject -routing. I did so with:
'routing': Ember.inject.service('-routing'),
Then the code to generate the URL from the transition is as follows...
let routing = this.get('routing');
let params = Object.values(transition.params).filter(param => {
return Object.values(param).length;
});
let url = routing.generateURL(transition.targetName, params, transition.queryParams);