redux-offline: Redux state is missing “offline” part from redux offline

I’m not sure what is best etiquette when it comes to opening issues vs. asking on stack overflow. I asked a question on stack overflow with the same title as this issue. I have also given it a bounty (closing in 3 days at the written moment). You can find it here:

https://stackoverflow.com/questions/50798722/redux-state-is-missing-offline-part-from-redux-offline

I will also copy and past the questions content here for convinience. If this is incorrect, please write needed changes and I will make them 😃

ORIGINAL STACK OVERFLOW QUESTION

I’m using Redux Offline in my Angular project, and now I want to enable cancelling an item in the outbox while in offline mode. Basically, I just want to filter on the outbox array to remove items I want to cancel/modify.

My problem is it is missing (undefined) from the state I receive in the top level reducer. I can see offline in the Redux Dev tool, and I can also get it via NgRedux.select() and NgRedux.getState().

Is there a reason why redux offline is not present in the state received in the reducers? Can I add it, and then change it via reducers? Or is there another to access and modify the outbox?

package.json:

"dependencies": {
     "@angular-redux/router": "^7.0.0",
     "@angular-redux/store": "^9.0.0",
     "@angular/animations": "^6.0.3",
     "@angular/common": "^6.0.3",
     "@angular/compiler": "^6.0.3",
     "@angular/core": "^6.0.3",
     "@angular/forms": "^6.0.3",
     "@angular/http": "^6.0.3",
     "@angular/platform-browser": "^6.0.3",
     "@angular/platform-browser-dynamic": "^6.0.3",
     "@angular/pwa": "^0.6.7",
     "@angular/router": "^6.0.3",
     "@angular/service-worker": "^6.0.3",
     "@redux-offline/redux-offline": "^2.3.3",
     "core-js": "^2.5.7",
     "reduce-reducers": "^0.3.0",
     "redux": "^4.0.0",
     "redux-observable": "1.0.0-alpha.2",
     "rxjs": "^6.2.0",
     "rxjs-compat": "^6.2.0",
     "zone.js": "^0.8.26"
    },
"devDependencies": {
     "redux-devtools-extension": "^2.13.2",
     "@angular-devkit/build-angular": "^0.6.7",
     "@angular/cli": "^6.0.7",
     "@angular/compiler-cli": "^6.0.3",
     "@angular/language-service": "^6.0.3",
     "@types/jasmine": "^2.8.8",
     "@types/jasminewd2": "~2.0.3",
     "@types/node": "^8.10.18",
     "codelyzer": "^4.3.0",
     "jasmine-core": "~2.99.1",
     "jasmine-spec-reporter": "~4.2.1",
     "karma": "~1.7.1",
     "karma-chrome-launcher": "~2.2.0",
     "karma-coverage-istanbul-reporter": "^1.4.3",
     "karma-jasmine": "^1.1.2",
     "karma-jasmine-html-reporter": "^0.2.2",
     "opn-cli": "^3.1.0",
     "protractor": "^5.3.2",
     "ts-node": "~5.0.1",
     "tslint": "~5.9.1",
     "typescript": "~2.7.2"
}

Please write a comment if you need any more information.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 22 (20 by maintainers)

Most upvoted comments

@echoes221 You were spot on! Below code logs the outbox and my action with all the data I need to make my cancel action work.

Thanks so much for the help. If you want to earn some quick SO points, you can write an answer at my SO question here: https://stackoverflow.com/questions/50798722/redux-state-is-missing-offline-part-from-redux-offline - if you’d rather save the time, I’ll write my own answer 😃

You guys rock 💪

import defaultQueue from '@redux-offline/redux-offline/lib/defaults/queue';
public queue = {
    ...defaultQueue,
    enqueue(outbox, action) {
        if (action.type === 'CANCEL_OFFLINE_ACTION') {
            console.log(outbox, action)
            return outbox;
        } else {
            return [...outbox, action];
        }
    }
};

Epics shouldn’t effect what you’re seeing in the reducer at all. redux-observable setup is very straight forward and should just look like:

createStore(
  s => s, 
  {},
  compose(
    applyMiddleware(
      createEpicMiddleware(combineEpics(epic1, epic2))
    )
  )
)

But if that all works, I don’t think that’s your issue. V1 setup of redux-observable is slightly different but it does introduce breaking changes, so be careful of upgrading - I’d read the migration guide here.

I digress, this isn’t the observable package here. I’ve not used redux with ng before - any chance you can do a basic setup in a playground (codepen etc) if the suggestion below doesn’t work? I think that maybe we’re tackling this the wrong way around as you won’t be able to do what you want to do at the level that you’re doing it because redux offline replaces it’s reducer in dynamically in the background.

Going back to your original question - you want to remove actions from the offline.outbox correct? You should be able to do that by writing your own queue implementation instead of trying to do it at the root reducer level.

You could try dispatch your 'CANCEL_OFFLINE_ACTION' as an actual offline action (to allow it to pass through the offline middleware) and do your state change in a custom enqueue function. Here’s a really rough example, it just filters out actions from the outbox that match the cancel actions Id, the cancel offline action is never added to the outbox:

// the action to dispatch
const action = {
  type: 'CANCEL_OFFLINE_ACTION',
  payload: {
    id: 123,
  },
  meta: {
    offline: {
      effect: { url: '' },
    },
  },
};

// the custom enqueue action
function enqueue(outbox, incomingAction) {
  return incomingAction.type !== 'CANCEL_OFFLINE_ACTION'
    ? [...outbox, incomingAction]
    : outbox.filter(
      outboxAction => outboxAction.payload.id !== incomingAction.payload.id,
    );
}

Note, this is completely untested and a complete shot in the dark. But the enqueue function is the one that is called in redux-offline’s reducer so it gives you the access you need to make the change…or at least I hope it will.

Thanks 😃 I have accepted your answer. Have a splendid day 😃