I have some data from a function in my app.component that I would like to store and use in other components. How can I achieve this?
Here is the function:
private async setupLocalUser(): Promise<boolean> {
try {
this.token = await jwtDecode(this.oauthService.getAccessToken());
//add user
this.userId = await this.userService.AddUser(this.token.email);
//add user session
this.userSessionId = await this.userSessionService.AddUserSession(this.token.email);
return true;
}
catch (Error) {
this.errorMessage = Error;
return false;
}
this.userSessionId is what I'd like to store for use as a parameter in different functions that are in other components. How can I achieve this?
Take a look at this post, I'm sure it'll be useful for your problem. As they say there, you could use a service or sessionStorage (more info here) to store the data so it can be accessed across the application.
I hope this helps you!
There is number of ways by using you can store/transfer data across the components. It totally depends on your situation/requirement. For example, you can use
Service's
web storage (Localstorage/ SessionStorage/ Cookies etc)
Global Variables
Variables as behaviour subject.
But I would suggest if the value is confidential you should store in a Global variable or using services. By doing so it's a bit hard for anyone to fetch data from the production build.
Let me know if you still have any query.
Related
So I've read the documentation and have followed everything so far. However, in the handleOnChange function, I cannot post the data because it gives the error:
ERROR
Here's how I'm currently trying to post the data, I'm open for any suggestions.
function handleOnChange(state, component) {
state.isValid
state.data
component
if (state.isValid === true) {
this.http.post(environment.paymentFunctionurl + '/', { amount: this.amount, content: state.data}).subscribe((res) => {
console.log(res);
})
}
}
I've tried storing them as variables but it results as undefined. What am I missing here?
Your error is with accessing http, it isn't part of this. You need to make sure http is added to this or likely put http on window so you can access it regardless of your scope.
Side note: your example is passing amount from the client.Do not do this in production!!!!
You might be just doing this while testing, but it's even bad practice in testing. A client may be malicious and change the amount and instead you should use your own backend/database to dictate how much to charge.
I have an out javascript module, and I want to get the auth key from the vuex store
This is my code, that's seems that it work
import store from '../../../store';
class ExternalApi {
constructor() {
const that = this;
that.configuration = { apiKey: '', basePath: '/api/v2' };
that.authorizationHeader = function authorizationHeader() {
const cstore = store;
if (cstore && cstore.state && cstore.state.accessToken) {
that.configuration.apiKey = cstore.state.accessToken;
}
const localVarHeaderParams = { };
localVarHeaderParams.authorization = `Bearer ${that.configuration.apiKey}`;
return localVarHeaderParams;
};
this.list = function list(params) {
const localVarPath = `${that.configuration.basePath}/list`;
const localVarHeaderParams = that.authorizationHeader();
return axios....
};
}
I want to know 2 things:
Does it the way to connect to store from javascript or there is a better way for doing it
Does this code can make me some securities problems.
Answering your first question, when you want to use the store from outside Vue just use its API as you are doing though you don't really need to check for the store or the state to be initialized.
Regarding security, storing the authorization token in JS will be vulnerable to XSS attacks, the best way to avoid (or mitigate) them is implementing a robust Content Security Policy (CSP) and using a low (5-10min) time to live for your tokens.
On a side note, you don't need to rename store to cstore and if you use class methods instead of adding function properties in the constructor you wont need to juggle with this. Also note that storing the token in memory will not survive a page refresh so you may want to store it in sessionStorage.
I have some general questions which are bothering me regarding the context API and local storage.
When to use local storage?, when to use the Context API and when would I use both?
I know that to persist data after the refresh I need something like local storage or session storage, so do I ditch the context API entirely and just store everything in the local storage? this way I can not only store data but also keep it on refresh? some insight would be really helpful.
What are some pros and cons?
Context API vs Local storage is apples vs oranges comparison.
Context API is meant for sharing state in the component tree.
Context provides a way to pass data through the component tree without having to pass props down manually at every level.
Local Storage is for storing data between sessions.
The read-only localStorage property allows you to access a Storage object for the Document's origin; the stored data is saved across browser sessions.
The right comparison might be Local Storage vs Cookies, Context API vs State-Management Library (not really, since Context is not a state management tool).
While you can store everything on the local storage (although it's not scalable and maintainable) it won't be useful.
It won't be useful because you can't notify your components on state change, you need to use any React's API for it.
Usually local storage is used for session features like saving user settings, favorite themes, auth tokens, etc.
And usually, you read once from local storage on application start, and use a custom hook to update its keys on related data change.
Here is a helpful recipe for useLocalStorage custom hook:
function useLocalStorage(key, initialValue) {
// State to store our value
// Pass initial state function to useState so logic is only executed once
const [storedValue, setStoredValue] = useState(() => {
try {
// Get from local storage by key
const item = window.localStorage.getItem(key);
// Parse stored json or if none return initialValue
return item ? JSON.parse(item) : initialValue;
} catch (error) {
// If error also return initialValue
console.log(error);
return initialValue;
}
});
// Return a wrapped version of useState's setter function that ...
// ... persists the new value to localStorage.
const setValue = value => {
try {
// Allow value to be a function so we have same API as useState
const valueToStore =
value instanceof Function ? value(storedValue) : value;
// Save state
setStoredValue(valueToStore);
// Save to local storage
window.localStorage.setItem(key, JSON.stringify(valueToStore));
} catch (error) {
// A more advanced implementation would handle the error case
console.log(error);
}
};
return [storedValue, setValue];
}
I have to validate that the user is logged in, using some token, that currently in the next example will already be set, for testing.
I have two options that I can think of.
Option 1
Do it on store's constructor:
export class MyStore {
#observable token = "sometoken";
#observable authenticated = false;
constructor() {
this.checkAuth();
}
#action
checkAuth() {
fetch("http://localhost:3001/validate/" + this.token)
.then(res => res.json())
.then(data => {
this.authenticated = data.validated;
});
// catch etc
}
}
Option 2:
Do it in my component's that uses the data, componentDidMount method.
Both of the ways work, but what is really the best practice to handle such state?
I would definitely go for the first option. If you don't always need the authentication - for example some parts are public - then just don't call this.checkAuth() in the store constructor. If all parts need authentication, then it looks good like this.
Option 2 should be avoided because that would make unnecessary roundtrips to the server to re-validate a token which was already validated. And in general MobX gives great tools to minimize the use of lifecycle methods and write a cleaner code.
I'm currently following this guide (https://www.youtube.com/watch?time_continue=1614&v=_kYUzNVyj-0) to implement authentication in my react, graphql and apollo application. In the guide they have this function:
async function context(headers, constants) {
console.log('calling context') // This never prints, so it's not being called.
const user = await getUser(headers['authorization'])
return {
headers,
user
}
}
Below that function I have my resolvers and mutation for the GraphQL. One of the queries is supoosed to get the current user and that looks like this:
export default {
Date: GraphQLDate,
Query: {
currentUser: (root, args, { user }) => {
console.log(user) // undefined
console.log('currentUser')
return hello
},
...
In the video they later access the values via object destructuring, or just importing the whole object in their arguments:
When I'm trying to access anything from the return object from the context function I get undefined. It's due to the fact that the function is never being called, and I don't know why. It's probably something dumb I'm missing here.
I made a Gist of the code that I want to get working if that might help my shining knight that will hopefully save my day.
https://gist.github.com/Martinnord/6d48132db9af1f9e7b41f1266444011c
I can add more context to my question if anyone like! Thanks so much for reading!
You need to export your context function for Launchpad to pick it up. So
export async function context(headers, constants) {
console.log('calling context') // This never prints, so it's not being called.
const user = await getUser(headers['authorization'])
return {
headers,
user
}
}
It's not fully clear IMO that launchpad is looking for that context function. This is a tricky topic as well since the context function isn't required to make things work it doesn't notify you that it isn't there.