Giter Site home page Giter Site logo

jasonmerino / react-native-simple-store Goto Github PK

View Code? Open in Web Editor NEW
878.0 12.0 82.0 2.19 MB

A minimalistic wrapper around React Native's AsyncStorage.

Home Page: https://www.npmjs.com/package/react-native-simple-store

License: MIT License

JavaScript 57.67% Java 7.17% Objective-C 25.61% Starlark 9.55%
react-native asyncstorage ios android

react-native-simple-store's Introduction

React Native Simple Store

Code Climate Build Status npm version npm

A minimalistic wrapper around React Native's AsyncStorage.

The react-native-simple-store is a good match for apps that are not using redux. If you have already found that your app needs to use redux and you need to persist data to the device it is recommended that you make use of redux-persist which provides a clean interface for storing data in your reducers to device.

Installation

npm install react-native-simple-store

Since this wrapper uses react-native-async-storage, it needs to be linked to work properly:

react-native link @react-native-community/async-storage

Use In Project

import store from 'react-native-simple-store';

Example Usage


Working With Objects


React-native-simple-store allows you to easily store data by assigning it a unique key. We will show you a few examples of just how easy it is to get started.

Saving and Retrieval

Updating

// Update the object stored under the key 'album'. We will add a new property of 'albumName' to this object.
store.update('album', {
  albumName: 'Blurry Face'
})

// Get updated object
store.get('album')
.then((res) =>
  console.log(res.albumName) // 'Blurry Face'
)

// Our object stored under the key 'album' now looks like this
{
artist: 'Twenty One Pilots',
  albumName: 'Blurry Face'
}

Working With Arrays


Arrays are easy to work with using react-native-simple-store's built-in "push" method. You can use the "push" method to create an array, or add data to the array. Behind the scene's react-native-simple-store will check if an array exists under the key you specified, if it does, it will add the new specified data to the existing array. If it does not exist, it will create the array for you.

Array Creation

// Save an array to the users device. We will give it the key 'shoppingList' for easy retrieval
store.push("shoppingList", "milk");

// ['milk'] is created and stored on the users device

Retrieval and Updating

// Get the array from the users device
store.get("shoppingList").then(
  res => console.log(res) // ['milk']
);

// Add data to 'shoppingList'
store.push("shoppingList", "coffee");

// Retrieve new array
store.get("shoppingList").then(
  res => console.log(res) // ['milk', 'coffee']
);

More "Advanced" Example

Instead of storing strings in an array like the above example, let's store objects. We will create a new array to store on the user's device named 'artists'.

const femaleArtist = {
  name: "Lady Gaga",
  age: 31,
  gender: "female"
};

const maleArtist = {
  name: "The Weeknd",
  age: 27,
  gender: "male"
};

// Creates a new array, and inserts this object into it.
store.push("artists", femaleArtist);
// Adds this new object to the end of the array.
store.push("artists", maleArtist);

// Our new array will look like this when we retrieve it
// [{
//   name: "Lady Gaga",
//   age: 31,
//   gender: "female"
// },
// {
//   name: "The Weeknd",
//   age: 27,
//   gender: "male"
// }];

Chaining


You can chain these methods as much as you'd like, as well as catch errors. Here is a lengthy example for you to reference.

store
  .save("coffee", {
    isAwesome: true
  })
  .then(() => store.get("coffee"))
  .then(coffee => {
    console.assert(coffee.isAwesome === true);
  })
  .then(() =>
    store.update("coffee", {
      isNotEssential: false
    })
  )
  .then(() => store.get("coffee"))
  .then(coffee => {
    console.assert(coffee.isNotEssential === false);
    console.assert(coffee.isAwesome === true);
    return store.delete("coffee");
  })
  .then(() => store.get("coffee"))
  .then(coffee => {
    console.assert(coffee === null);
  })
  .catch(error => {
    console.error(error.message);
  });

// using the .push method for storing arrays
store
  .save("coffeeTraits", ["rich"])
  .then(store.push("coffeeTraits", "smooth"))
  .then(store.get("coffeeTraits"))
  .then(console.log); // ['rich', 'smooth']

Deleting Data


Deleting the data on the user's device is just as easy. Just insert the key of the data you want to remove as the argument to the "delete" method, and you are done!

store.delete("album"); // Bye bye

License

MIT

react-native-simple-store's People

Contributors

dzuz14 avatar headlessme avatar jasonmerino avatar keeleycarrigan avatar mrfoxpro avatar oas avatar shercoder avatar younes200 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-native-simple-store's Issues

RN simple store is breaking my mocha tests

Whenever I test an object that has RN simple store I get the following:

/Users/gantman/Documents/Projects/rn/trackops-mobile/node_modules/react-native-simple-store/index.js:3
var {
    ^

SyntaxError: Unexpected token {
    at exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:404:25)
    at Module._extensions..js (module.js:432:10)

here's a screencap, if that helps at all...

image

I'm using mocha and chai.

[Android] Please explain how this works

I did something like this-

Inside signin component:
store.save('credentials', {username: this.state.username, password: this.state.password});

Inside home component:

getData: function(){
    return store.get('credentials')
        .then((data) => {
            console.log(data);
            //return 'Username: ' + data.username + ' Password: ' + data.password;
        });
  }

it is returning 3 objects-

Object {username: "android", password: "aa"}
Object {username: "android", password: "aa"}
Object {username: "android", password: "aa"}

Why is get() returning 3 objects? Is there anything wrong with the usage? Thank you in advance.

store.delete delete by ID

if I have key array structure like this

'Bookmark' = {[ ID : 1, isBooked: true ],[ ID : 3, isBooked: true ]}

I want delete / remove ID : 1, how to do it ?

Couldn't read row 0, col 0 from Cursor Window.

I am getting the error Can't read row 0, col 0 from Cursor Window. Doing a little research it seems like there may be a limitation of 2MB for sqllite. My assumption are you are using sqllite in this implementation. Not sure how you are using it, but wondering if anyone has come across and if there is a workaround. I am saving some large JSON chunks using this library. The error is only occurring on Android.

Add multi-get

Sometimes getting two values from the simple store would be nice as a convenience method without having to call Promise.all([store.get(KEY_ONE), store.get(KEY_TWO)]).

store.update retains original store?

Calling store.update doesn't overwrite all the existing properties does it? If I have 10 properties and call update on a single one...it will just update that one? Even if it is simply an addition (an 11th property?).

Just want to make sure. Running into an issue with store unexpectedly deleting sometimes.

updating an object of objects creates duplicate keys

lets say the store has "favoriteAlbums"

favoriteAlbums: {
    a: {...},
    b: {...} 
}

Paradoxically, if you do this, you'll end up with a duplicate key in your favoriteAlbums object:

store.update('favoriteAlbums', {b: {,,,}}

// so now favoriteAlbums looks like this
favoriteAlbums: {
    a: {...},
    b: {...},
    b: {,,,} 
}

Ideal functionality would be to overwrite the nested object.

.save and .update could return key|values they saved/updated

I suppose we could benefit from returning as then parameter what we just stored using .save and .update if we want to do something else with that data. In case below I want to make sure my data is saved in storage before I can do something else with the data returned from API. Because simple store is Promised based when we want to .save something, our then function doesn't have any parameter. Maybe it would be good to return same properties we passed to .save as then parameter. This is how we need to do it now:

import store from 'react-native-simple-store';

fetch('some_URL', options}).then(resp =>
  store.save([['token', `Bearer ${resp.token}`], ['user', resp.user]]))
).then(() =>
  store.get('user')
).then(resp =>
  // do something with user object in my code
)

or better option:

import store from 'react-native-simple-store';

let temp;

fetch('some_URL', options}).then(resp => {
  temp = resp;
  return store.save([['token', `Bearer ${resp.token}`], ['user', resp.user]]))
}).then(() =>
  // do something with resp which is saved in temp variable
)

but it would probably be best to return object with key|value pairs of all the things we just saved/updated:

import store from 'react-native-simple-store';

fetch('some_URL', options}).then(resp =>
  store.save([['token', `Bearer ${resp.token}`], ['user', resp.user]]))
).then(resp =>
  // resp should now be { token: 'Bearer some.token.here', user: {...} } and we can continue as we know it's been saved into AsyncStorage
)

What do you think? Does this make sense?

I can’t make it work on a real iOS device

Hello,

Currently I can use this library with the simulator by running react-native run-ios, but when I open the xcode project and run the app on a real device (debug or release), the store doesn’t work anymore. Is there something I’m not aware of ? I’m using react-native 0.39.2.

react-native-web support

Can you support react-native-web?

The library could detect if the platform is web and then implement the same methods with localStorage instead.

What do you think?

As of now, any react-native-web project fails because the asyncStorage is not well supported there.

See this thread:
react-native-async-storage/async-storage#52

Unable to push to array using a loop.

I have an array of purchased item keys that I store using this module. Saving one at a time (when the purchase is made) works perfectly with store.push however I now need to be able to store more than one value at a time in the array.

To do this I assumed it would be possible to use a for loop and just call store.push inside.

However this is not the case and it only seems to store the final iteration ignoring any previous calls to the store method.

for (i = 0; i < purchases.length; i++) {
store.push('devicePurchasedKeys', key)
}

Could you please advise if there is a method that will achieve this as if there is I can't see it mentioned.

Sometime the keys and value in the store all dispeared

The issue happened on android, when I open the splash page ,it will judge it has logined or not from the key-value from store,
But, if the Rn-app error or debug-onReload, the keys and values in store all disppeared . I don't know why.

I use "store.get('access_token')); store.keys()" to get the promise,and I found the issue.
error
ok

What is it?

Unhandled JS Exception: TypeError: TypeError: (0 , _reactNativeSimpleStore.default) is not a function

How would I store an array?

var location ={someCoord}
store.get('locations').then(locations => {
      locations.push(location);
      store.update('locations', {
        locations
      })
    });

Seems to bug out because locations isnt an existing array. Do I initialize it at some point?

store.save(key, value) stopped working

  • All of a sudden, store.save(key, value) has broken down.
  • It was functioning properly (verified by store.get(key)) until I (once) executed store.delete(key)

  • While I can verify that data is being saved by invoking store.get(key) immediately after store.save(key, value), the data won't persist after re-launching the app (in fact I'm not sure after how long the data vanishes)
  • Furthermore, I didn't install any new packages (or modified any existing ones), which could be blamed for it

After (obviously) removing store.delete(key) call, I tried the following without luck:

  • uninstalling app on iOS simulator before re-installing
  • restarting packager with --reset-cache
  • rebooting my laptop (facepalm!)
  • taking fresh clone of the (private) repo and re-installing all packages

Configuration:

  • RN v0.46.4
  • react-native-simple-store v1.3.0

Get all keys

AsyncStorage has a method getAllKeys, how can I use it via simple-store?

Updating property of object within stored array

I have written the below function to update the property of a supplied object stored in an array. To do so, I used the method mentioned in #31 for deleting items.

Trouble is since I'm using .push, updating an item causes it to be rendered at the bottom of the array. This causes items to move in the FlatList unnecessarily.

Is there a more efficient method for updating a property of an object within the array (without causing this issue using .push)?

plusProgress = (itemId, progress) => {
  const foods = this.state.foods.filter(({ id }) => itemId !== id);
    const updatedItem = {
      itemId,
      progress: progress + 1
    };
  foods.push(updatedItem);
  this.setState({ foods });
  store.save('foods', foods);
}

Thanks.

Removing object from array

Not sure if this can be made easier via your module, or if I need to rethink the structure of how I am storing my data, but here is the problem I am having.

A portion of my app allows users to schedule alarms. When they schedule an alarm, it creates an object inside of a currently existing array with key of 'alarms'. Just for an example, let's pretend "alarms" is an empty array right now, and my user clicks the save alarm button. In the code, this is what it does:

    const id = new Date()
    const newAlarm = {
      id: id,
      hour: finalHour,
      minutes: finalMinutes
    }

    store.push('alarms', newAlarm)

This works perfect, and will push as many new alarm objects as the user wants into the array. However, when I give the user the ability to delete the alarm, this is where I am stuck.

To make my example easier to explain, let's pretend that my user created two more alarms after the initial one they just made. "alarms", now is an array with three objects inside of it. Say the user now wants to delete the first object in the array, I have to do something super hacky in order to make this happen.

In the particular view that I have, my React component already has the alarms array saved into local state so I do something like this:

deleteAlarm = id => {
   const alarms = this.state.alarms
   let newAlarms = []

   for(var i = 0; i < alarms.length; i++) {
      let alarm = alarms[i]
      if(alarm.id !== id)
         newAlarms.push(alarm)
   }
  // Can't figure out what to do from here...
}

Basically, I am stumped as to how I could easily remove one object from my existing array, then just update it in order to save the changes. Creating a for loop and a new array with all of the other objects except for the one I want deleted, seems like craziness to me. I was wondering if your module provides an easy way to do so, and I am just unaware of how to do it.

Await/Async

Can i use this library with async/await words?

this.props becomes undefined

Hi!

First of all, great library! It's fantastic and I'm making some pretty heavy use of it.

One issue I thought I'd report. Unless I'm completely mistaken, after calling store.get('X'), the props property of this, this.props, becomes undefined. For the life of me I can't figure out why.

My current implementation looks something like this

class MyComponent extends Component {
 componentDidMount() {

     store.get('some_data')
     .then(function(data){
        console.log(this.props) // this here is undefined
     })
 }
}

Perhaps this has something to do with this while inside the then call then references the store class rather than the component's. Not sure if this is the desired implementation of that or not, but just thought I'd bring it up.

My solution to address this was to assign this.props to a variable before calling methods from the store, and in .then calls for store methods I reference that variable to get what I need from this.props, etc.

Thanks again for the awesome lib!

AsyncStorage is null

I get this error, i followed the instructions but its not working.

I'm using the expo client to build the app. Using AsyncStorage itself works fine.

How to return stored value in a function.

Hi,

I'm having trouble figuring out how to retrieve a value from a custom function that accesses the store. I keep getting an undefined value despite having access to the value from within the function.

My code:

export function fetchToken() {
  store.get('userToken')
  .then(token => {
    if (token) {
      return token;
    }
  })
}

If I console out the token in the above function it's clearly there.

But when I try to use the above function elsewhere like so:

let token = fetchToken() I get an undefined.

Clearly, I'm missing something here. Any help at all would be greatly appreciated .

Thank you!

Update NPM

Could you publish the latest version to NPM?

I want to delete an object in an array

Nice to meet you.
I am not good at English, so the sentences may be strange. I'm sorry.

I am creating a todo application for ios with react-native.
In order to store data in local storage, I would like to configure the store as follows. ↓

Index [
  Item1 {
    Todo: "task",
    Checkbox: false
  },
  Item2 {
    Todo: "task",
    Checkbox: false
  }
]

"Index" and "item" are keys used in push and delete.
"Item" is a random string.

I execute delete(index) when deleting all tasks. Since all task objects are in the index array, if index is specified as an argument of delete method, all tasks are deleted from local storage.

The problem is when deleting one particular task.
There is a delete button in each task, and when you tap it, the task is deleted. I have created a method for deleting a specific task. ↓

DeleteTodo (id) {// id is the key of the task to which the delete button is tapped
    ls.keys ()
    .then (key => {
      key.map (key => {
        If (key === id) {... *1
          ls.delete (key)
        }
      })
    })
    ls.get ('index') ... *2
    .then (list => {
      console.log (list) ... *3
    })
  }

In the part of *1, "If the key of the task tapped in all keys exists, the task is deleted" is executed.
*3 checks whether the task was properly deleted.
Since all the tasks should be present in the index key, index is specified for the get method of *2.

However, console shows tasks that should have been deleted. The tapped task has not been deleted. Try to get all the keys with the key method and check the console.log, the key of the tapped task was not displayed. In other words, only the key of the tapped task is deleted, and the task itself is not deleted.

How can I delete a specific task object that exists in an array?
What is wrong with the method I created?

Thank you for creating react-native-simple-store.

Re-invoke 'store.get' after calling 'store.push'

Hi, thanks a lot for this, it's exactly what I needed for my project.

I have one query....

After adding a new item to an array of objects, how can I force store.get to re-invoke? This would re-render my list of data to reflect the changes.

And how can I add res to state for rendering?

onLoad = async () => {
  store.get('array')
  .then((res) =>
  console.log(res)
);
}

saveData = () => {
  const { title } = this.state;

  const data = {
    title
  };
  store.push('array', data);
}`

Thanks in advance

Outdated bookstore

It would be nice to create a new tag with the latest changes since it is quite outdated from the main branch.

Last tag 7 jun 2017

2019-07-03_1534

Thanks for help with this plugin.

@jasonmerino @oas

Change "update" to a deep merge

First, really like this little module. It really simplifies interacting with AsyncStorage.

I did notice one thing though. When you do an update it doesn't do a deep merge. This comes into play as soon as any key off your main storage item is an object because Object.assign doesn't do a deep merge. For example if I want to really organize my saved data and have a key for all user info that's separate from any other data I need to repeated get the current storage object, do a merge, then reassign it or my user data will keep getting messed up.

So I have:

"mainStorageKey": {
    "other_data": "something"
    "user_info": {
        "email": "[email protected]",
        "token": "345983nfk23jrh239r3",
        "lat": 0,
        "lng": 0
    }
}

Whenever I want to update the user's latitude and longitude I need to pull down the main storage key off AsyncStorage and then merge the new coordinates with the user info. I see it's going a shallow copy here, but maybe I'm looking at this the wrong way or is there another way to accomplish what I'm talking about? Seems like adding lodash could add this functionality really easily.

get fails when there is no value saved for such key

this: return JSON.parse(value);

results in this error:
SyntaxError: Unexpected token u in JSON at position 0
at Object.parse (native)
at /Users/xxx/xxx/xxx/node_modules/react-native-simple-store/dist/index.js:24:17

when called with a key that has no value in AsyncStorage because the value is undefined and can't be parsed into JSON.

Compatibility with react-native 0.40

Since December version
react-native team introduce a breaking change that affects third party modules.
I'm quoting here the message from the release notes. It would be great if you could upgrade the package 🎉 Thanks !

iOS native headers moved

This change affects all native modules and application code on iOS that refer to react native .h files
After e1577df, Native code on iOS must refer to headers out of the react namespace. Previously the following would work:

#import "RCTUtils.h"

But now all headers have been moved:

#import <React/RCTUtils.h>

This means that all iOS native libraries need a major version bump for RN 0.40. We attempt to minimize changes of this magnitude, and we apologize for any inconvenience caused.

EDIT : Consider also using the macro suggested in the following article, to support 0.40 and keep compatibility with previous versions.
https://medium.com/@thisismissem/how-to-upgrade-react-native-modules-in-a-backwards-compatible-manner-a5b5c48d590c#.vh7nbtd26

How to check the existence of a value in storage?

If I simply want to check if an object exists in the store, how do I do that? All I see are get and create methods that already factor in the existence of an object.

My specific use case is that if the object doesn't exist, I want to create it with certain values (default values) -- otherwise I want to leave it alone.

Unable to resolve module `@react-native-community/async-storage`

Hi,
I just updated to react-native 0.59.8 from 0.58.
I updated as well to react-native-simple-storage from 1.3.0 to 2.0.0 to remove the warning regarding async-storage.

I am getting the following error on runtime:
Unable to resolve module @react-native-community/async-storage from /Users/maryasadek/RN/Washmen/node_modules/react-native-simple-store/dist/index.js: Module @react-native-community/async-storage does not exist in the Haste module map

I tried resetting node modules, and the cache, but it did not help.
image

Update with typescript

This is annoying to use with typescript as it does not contain any typescript definitions or types. This would be appreciated as typescript is becoming more popular.

Why doesn't update use AsyncStorage.mergeItem?

Hey,

Thanks for the package, it is great.

A question: why does update gets an item to the js side, deep merges it with the provided value and saves the result, rather then use AsyncStorage.mergeItem, which handles the deepMerge on the native side, thus saving an unnecessary cross over the bridge?

If there is no reason, I can create a pull request to use mergeItem instead.

Thanks again!

Arrays not working

I've been following the examples and pushing objects into an array with simple-store but when I try to retrieve from it again I only get the last value pushed. It seems like either the get function only returns the last item or the push function overrides the array

TypeError: Cannot read property 'cache' of undefined

I updated react-native-simple-storage from 1.3.0 to 2.0.0 to remove the warning regarding async-storage.
But it fails with :

error: bundling failed: TypeError: Cannot read property 'cache' of undefined
    at module.exports (/Project/node_modules/react-native-simple-store/babel.config.js:2:6)

After removing this line


it works fine.

A PR is available it makes sens to you.

I Am using "@babel/core": "^7.4.4"

Any idea ?
Thanks

Update or Create function

Would a update or create function call be of use?
For instance if I want to update an item if it exists already, else create it.

Not working with expo-cli

Hello,

I really like this package and this might be a non-issue but I was wondering if there is a way to use this package with the expo-cli. I followed all the steps but when I try react-native link @react-native-community/async-storage it throws an error which is perfectly normal.

Is there another way to use this package with expo-cli?

If I don't link it then I have this error: Unable to resolve module @react-native-community/async-storage

Why update and save

Why there is update and save methods? They basically do the same thing in key value db.

Make docs easier to read

Docs are helpful, but should be split up into different sections, instead of one big promise. I can help out with a pull request for that if needed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.