how can i save object in mobille storage using react native - javascript

I am building an application in which I want to save user data. and user able to see that data later. I am using AsyncStorage.. i want to store multiple values in one key. I used AsyncStorage.setItem.. here is my code..
var obj ={
name : "sabih",
color : "blue"
}
AsyncStorage.setItem('myKey', JSON.stringify(obj))
.then(() => {
console.log('data saved')
})
but when i get data with AsyncStorage.getItem. it gives me like this
{"name":"sabih" , "color" : "blue"}
Code here
AsyncStorage.getItem("myKey").then((data) => {
var userData = JSON.parse(data)
console.log(userData, 'Get Values')
}).done();
How can i set name's and color's value in state. or how can i render these values in my react native application..
Thanks in advance.
and please attach a snap of solution if possible..

Create a function inside your file and call that function passing your asyncstrorage value as parameter as below :-
_renderDetail=(item)=>{
this.setState({user:item});
}
and inside your asyncStorage code edit as :-
AsyncStorage.getItem("myKey").then((data) => {
var userData = JSON.parse(data);
console.log(userData, 'Get Values');
this._renderDetail(userData);
}).done();
and then you can use this state variables inside your render function as :-
<Text>{this.state.user.name}</Text>
<Text>{this.state.user.color}</Text>

Related

Javascript Axios get with conditional params

I am trying to get some data from an API. The problem is that the GET call could take none or some of the filters. I have tried but am not sure how/if I can create a URL with conditional filters.
actions: {
InstitutionSearch(value, id){
let fips = id['ParamValues'].find(o=>o.param==='fips')['value'];
let region = id['ParamValues'].find(o=>o.param==='region')['value'];
axios.get('https://educationdata.urban.org/api/v1/college-university/ipeds/directory/2019/',{
params:{
fips: ,
region: region,
offering_highest_level: 3
}
})
};
}
This is a vue application, with the code above running inside a vuex store. The id that is being passed in is an array of objects, that is taken from a search filter form. The problem that I have is that my query could include either fips or region or none.
My initial thought was the put fips and region equal to 0, but that does not work with my API. I am not opposed to building a query string inside conditionals, but there has to be an easier way. The following is an actual query for the data that I am working with https://educationdata.urban.org/api/v1/college-university/ipeds/directory/2019/?offering_highest_level=3.
With some amazing help, I figured out a simple solution. I created an empty object and then ran a conditional check on my parameters and only added them, if they met my qualifications. I then passed that object in as the parameters, and everything worked.
let fips = id['ParamValues'].find(o=>o.param==='fips')['value'];
let region = id['ParamValues'].find(o=>o.param==='region')['value'];
//code change
let params = {};
fips.length > 0 ? params['fips'] = fips.join(',') : null;
region != 0 ? params['region'] = region : null;
//code change
axios.get('https://educationdata.urban.org/api/v1/college-university/ipeds/directory/2019/',{
params
}).then(response=>{
console.log(response.data.results);
});
useEffect(() => {
axios
.get(
`http://stream-restaurant-menu-svc.herokuapp.com/item?category=${props.data}`
)
.then((response) => {
console.log("This is to show sub-categoary " + response.data);
setSubcate(response.data);
})
.catch((error) => {
console.log(error);
});
},[props]);

Add item to state after post in API get the id

I have a component where I can click to "add a study". This click triggers two things :
1 - post in my API
2 - adding to my state to re-render the component.
So, it works BUT when I record the data in my state, I have not the ID of the study and I need it after. So is it possible to do something to have this ID ? Or I am forced to re-call my API to get all my studies ?
My code in my component :
const addStudy = {
name : this.newStudy.nameStudy,
status: "In prepa",
project: "api/projects/" + this.newStudy.currentIdProject,
compareStudy: false,
basic: true
}
axios
.post('http://127.0.0.1:8000/api/studies', addStudy)
.then(this.$store.commit("addStudie", {projet : this.newStudy.currentIdProject, study :addStudy}))
And in my store :
addStudie(state, {projet, study}) {
const theProject = state.listProjects.projects.find(p => p.id === projet)
theProject.studies.push(study)
}
Thanks a lot
i seems there is an issue with the request. In my opinion, it should change to
axios
.post('http://127.0.0.1:8000/api/studies', addStudy)
.then((result)=>{
this.$store.commit("addStudie", {projet : this.newStudy.currentIdProject, study :result
})
})
if you have any problem place let me know
You can save your ID in the localStorage that saves key value string data on the client side (browser)
addStudie(state , id) {
// do somthing with state then save it into localStorage
localStorage.setItem('myID', id);
}
And a store getter that returns the id from localStorage
theId(state) {
const savedID = localStorage.getItem("myID")
return savedID
}
if(theId()){
// do something with your ID
}
else{
// ID is not saved in the localStorage yet , call the API
getDataFromAPI()
}

Async issue with State in React Native

I'm trying to build a simple app that lets the user type a name of a movie in a search bar, and get a list of all the movies related to that name (from an external public API).
I have a problem with the actual state updating.
If a user will type "Star", the list will show just movies with "Sta". So if the user would like to see the actual list of "Star" movies, he'd need to type "Star " (with an extra char to update the previous state).
In other words, the search query is one char behind the State.
How should it be written in React Native?
state = {
query: "",
data: []
};
searchUpdate = e => {
let query = this.state.query;
this.setState({ query: e }, () => {
if (query.length > 2) {
this.searchQuery(query.toLowerCase());
}
});
};
searchQuery = async query => {
try {
const get = await fetch(`${API.URL}/?s=${query}&${API.KEY}`);
const get2 = await get.json();
const data = get2.Search; // .Search is to get the actual array from the json
this.setState({ data });
} catch (err) {
console.log(err);
}
};
You don't have to rely on state for the query, just get the value from the event in the change handler
searchUpdate = e => {
if(e.target.value.length > 2) {
this.searchQuery(e.target.value)
}
};
You could keep state updated as well if you need to in order to maintain the value of the input correctly, but you don't need it for the search.
However, to answer what you're problem is, you are getting the value of state.query from the previous state. The first line of your searchUpdate function is getting the value of your query from the current state, which doesn't yet contain the updated value that triggered the searchUpdate function.
I don't prefer to send api call every change of letters. You should send API just when user stop typing and this can achieved by debounce function from lodash
debounce-lodash
this is the best practise and best for user and server instead of sending 10 requests in long phases
the next thing You get the value from previous state you should do API call after changing state as
const changeStateQuery = query => {
this.setState({query}, () => {
//call api call after already changing state
})
}

React JS Local Storage update on view change

How can I update certain properties of a local storage item or object as new data is inputted throughout the user journey and not lose what was previously entered or if the user decides to update?
My journey of 5 containers consisting of asking the user to input the following:
Name: string
Avatar: integer
Favourite Genres: multiple strings
On the first view I have created the local storage object / item that sets the name within the handleSubmit function.
handleSubmit(event) {
event.preventDefault();
//Profile object
let profile = { 'name': this.state.name, 'avatar': null, 'genres': '' };
// Put the object into storage
localStorage.setItem('profile', JSON.stringify(profile));
// Retrieve the object from storage
var retrievedObject = localStorage.getItem('profile');
//Log object
console.log('retrievedObject: ', JSON.parse(retrievedObject));
//On form submission update view
this.props.history.push('/profile/hello');
}
On my second view I want to update only the avatar property and maintain what the user had inputted in the previous view.
I'm doing this within the handleSelect function like so:
handleSelect(i) {
let selectedAvatarId;
let avatars = this.state.avatars;
avatars = avatars.map((val, index) => {
val.isActive = index === i ? true : false;
return val;
});
this.setState({
selectedAvatarId: selectedAvatarId
})
//Profile object
let profile = { 'avatar': i };
//Update local storage with selected avatar
localStorage.setItem('profile', JSON.stringify(profile));
}
You will need to read the existing value from localStorage, parse it as JSON and then manipulate the data, and write it back. There are numerous libraries out there for easily working with localStorage, but something along the lines of this should work as a generic function:
function updateProfile = (updatedData) => {
const profile = JSON.parse(localStorage.getItem('profile'));
Object.keys(updatedData).forEach((key) => {
profile[key] = updatedData[key];
});
localStorage.setItem('profile', JSON.stringify(profile));
}
If you use object spread, it could look a lot cleaner too:
function updateProfile = (updatedData) => {
const profile = {
...JSON.parse(localStorage.getItem('profile')),
...updatedData
};
localStorage.setItem('profile', JSON.stringify(profile));
}
There should probably be some safety checks in the above code, but hopefully gives you an idea for a starting point.
The only option as far as I know is to get it as a Json, amend accordingly and then save it is again.

Return all data back in new node in Firebase Cloud Functions

This is my inputted data:
This is my function:
exports.updateAll = functions.database.ref('/update/{uid}/{values}').onCreate(event => {
const data = event.data.val()
console.log(data)
return db.ref(`somewhereElse/somepath/`).update(data)
})
This is the error I am recieving:
Is it possible to update all the created values back into another path? I thought creating a const with the event.data.val() would work, but then I get the error.
Your reference for the onCreate trigger is /update/{uid}/{values} and so the event data will be that of the values. For example, the event data for /update/{uid}/email would be a string, and this is not an object containing children.
If you have a reason for needing to trigger this way, there is a solution to the error you are getting.
functions.database.ref('/update/{uid}/{values}').onCreate(event => {
const key = event.params.values
const value = event.data.val()
console.log(key, value)
return db.ref(`somewhereElse/somepath/{key}`).set(value)
})
The key value that was created can be retrieved from the event params and data. Then we can interpolate the key into the somewhere else ref, and set the value instead of updating it.

Categories