Skip to main content

Vuex 🤢

Why we use Vuex in a React Native app​

Vuex is essentially Vue's version of Redux. The reason why you're seeing this is because at the time of creating this project, there was a need to rapdily launch, and rather than re-writing a massive amount of data store code in Redux, we just imported Vuex and the website project as a dependency on the app. Yeah, it's terrible - there is ongoing work to drop this as a dependency and replace it with something more sane.

Vuex Hooks​

The following hooks can be used to access the vuex store, which is separate from our redux store, and is imported from the frontend project. Note the following section regarding migrating away from using these hooks, and vuex generally.

Currently available vuex hooks:

  • useStateSelector e.g.
const betslipSingleItems = useStateSelector<string[]>(
(state) => state.betting.betslip.singles
);
  • useGetterSelector e.g.
const multiBetOptions = useGetterSelector((getters) =>
getters["betting/getMultiBetOptions"]()
);
  • useVuexDispatch e.g.
const dispatch = useVuexDispatch();
...
dispatch('betting/saveBetslip', null, { root: true })

Vuex Migration​

This document should hopefully provide an overview of what stores still need to be migrated. Any unmentioned vuex stores should already be migrated or are irrelevant. Note this document is written for the current state of the app at this point in time and should be updated based ongoing migration work.

This is a list of stores which still need to be migrated/affected:

pricing markets sports

toolbox

betstatement transactions

account user rnUser

contentful

offers

categories configStore domain

Sports Migration​

Once sports is fully migrated to graphql, the following Vuex stores will become obsolete.

pricing markets sports

Status of as GQL Sports of now:

Completed:

  • Sports Home Screen (LB + Neds)
  • Sports Regions Screen
  • Sports Leagues Screen

To be done:

  • Competitions Screen (incl. season pricing)
  • Match Card (incl. 2 different layouts, SGM, 6-pack)
  • Live Betting

Notes:

  • Don't forget to test deeplinking to those pages
  • Because with GQL we are no longer persisting event cards in a store, will need to take into considerations for other parts of the apps which may rely on these i.e. BetTicker, BetMaps

Toolbox Migration​

Refers to the toolbox store. This one hopefully shouldn't be too hard as it's fairly isolated and most of it is already included with betslip core, the only parts which will need to be re-written are flucup & switchPromos

Transactions​

Refers to transactions & betstatement store. Will also affect "My Bets" (Race Card)

This is a major piece of work and my recommendation is to completely overhaul (rewrite) the transactions section as it is not structured very well and is also very slow in comparison to other sections of the App. The BetCard.tsx component is key here but it's doing way too much and should be split up and structured in a more flexible/modular/re-usable way as this part will most likely see quite a lot of changes as new betting products get created.

All pending bets / bet statement data should supposably come from this endpoint (with varying query params):

/rest/v1/transactions/?method=transactionsbyclientidwithfilters

All of this data should be stored one way or another into a dedicated reducer. Also note that the data is very heavy so the bulk of the store work would be creating a lot of well optimised selectors. In the past there were numerous instances where the entire App would freeze as it's trying to do some transformations to some exotic bets with thousands of combinations.

Account + User​

account

This store doesn't seem to contain much data and seems to be only dealing with deposits & account verification details and is reliant on data from the user store. Not sure why this is a separate store could possibly be combined into the user store.

user, rnUser

This is a slightly larger piece to migrate, but can be split into individual sections. Note that some stuff from the store has already been pulled over to RN e.g. logged in state, favourite sports, show balance etc.

The table below details the relevant sections which need to be migrated:

SectionDetails
clientContains the client data, check response from /v2/client/client-details
fundsAvailable deposit methods & stored credit cards
bankAccountsStored bank accounts
canDepositWhether or not the client can deposit based on set deposit limits
responsibleGamblingMost of this should be migrated already with new PA, I think depositLimits still needs to be migrated though
promoEligibilitycomes from /v2/client/client-details
gotMerchantCardApiResponse, merchantCardStatus Merchant card related, not sure if relevant
cashinAccount, cashInDepositCode, cashInNotificationPossibly irrelevant, need to confirm
maxDeposit, minDepositShould come from config & Vue.api.post('client', 'max-deposit-allowed')
canWithdrawShould be based on paypal + credit card + user verification status
canCashoutComes from /v2/client/client-details
canViewPendingWithdrawalsComes from Vue.api.get('finance', 'CanViewPendingWithdrawals') looks like
creditLimitComes from Vue.api.get('client', 'LookupCreditLimit')

rnUser

This store only contains one action and looks like it's only used to update the notification badge count.

Contentful/Promotions​

contentful

This is the promos stuff:

  • promo indicators for events/markets (should be mostly migrated to gql)
  • promotions page (should already be migrated to gql)
  • promotional markets

Though not 100% confirmed, I believe we should aim to remove the dependency on contentful completely for RN and let graphql handle the promo data.

Offers​

offers

Appears to be mostly self contained, does have a few references to user but are for the pinned user details stuff it seems so can mostly be worked around.

Misc​

There are these 2 stores categories, configStore which are fairly self explanatory. There is already an RN equivalent of these 2 stores and no RN code should need to reference these 2 vuex stores. So basically, no migration needed here.

domain - this looks like it's the quick links and featured stuff should become obsolete once sports has been migrated to gql

Plugin Migration​

The plugins can be thought of as standalone modules that accomplish a variety of tasks. They are based on the singleton pattern and are currently attached to the global Vue object. Migration to RN should aim to keep the singleton pattern without the dependency on Vue.

The current plugin references are accessed in RN code via utils e.g. utils().tracking.addEvent(...). I suggested re-creating these plugins in TS (either in RN proj or ui-core proj depending on the plugin) without the dependency on Vue and instantiating them on RN side. To ensure compatibility with vuex during migration you may need to do something similar to how some plugins currently work with ui-core and still "install" them via a plugin shell in frontend.

api​

TODO

auth​

Auth plugins have been migrated to ui-core already, so we just need to create a basic vender agnostic shell interface to interact with core auth |

client​

TODO

fingerprint​

TODO

format​

TODO

push​

TODO

session​

This one has a few dependent plugins which need to be fully migrated first.

There is a list of functions used by the dependent plugins for easy reference:

auth

  • decodeToken
  • getClientId
  • refresh
  • checkForTokenExchange
  • setClient
  • getClientUsername
  • getUserInfo

storage (already migrated)

  • deleteTokenData
  • setTokenData

visibility

  • subscriptions
  • isVisible
  • timeHidden

network

  • subscriptions
  • isOnline

There are also a number of subscriptions:

  • addTracking
  • validChanged (client)
  • clientDataUpdated (client)
  • isLoading (client)

storage​

This one is pretty much already migrated just need to remove the vuex dependency.

tag-manager​

This plugin currently depends on some data from vuex store (mainly data related to the user/session) so will need to take that into account when migrating

tracking​

TODO

visibility​

Already natively implemented, just need to remove the vue dependency and add subscription capability to visibilityChanged event