I am trying to add google tag manager to a project where we are using Redux Saga. I'm not very familiar with either redux saga or gtm. What I am trying to do is create a gtm that looks as follows:
TagManager.dataLayer({
dataLayer: {
event: 'login',
userId: user.UserID,
locale
}
})
I want the event to trigger when a user logs in. The problem I have is that I can not get the UserID since the event is triggered before I have the userid and therefore shows up as undefined
in gtm. The saga looks like this:
// Login user
export function* loginSaga(action) {
yield put(actions.loginStart());
const payload = {
username: action.username,
password: action.password
};
try {
const response = yield axios.post('/api/auth/login', payload);
const locale = yield select(state => state.common.locale);
const user = yield select(state => state.user.user);
if (response.data.success) {
const token = yield response.data.data.Token;
yield cookies.set('uid', token, { path: '/' });
yield put(actions.getUser(token));
yield put(actions.loginSuccess(token));
yield put(actions.closeModal());
TagManager.dataLayer({
dataLayer: {
event: 'login',
userId: user.UserID,
locale
}
});
}
Is it possible to wait until userid is no longer undefined and THEN trigger the gtm and what would be the best practice to do so?
Let me know if you have any questions, which I assume you have. I'm pretty new to this as I mentioned earlier.
Thank you!
With the below lines of code, after you make axios.post, you are not storing the user details state but very soon in the next line you are trying to grab user/locale details. EDIT - Also the user
needs to be obtained from the store which is updated by another ation. Therefore they are undefined.
Solution:
Use take which will wait the action to be completed.
Like this
try {
const response = yield axios.post("/api/auth/login", payload);
// wait until one of the success or failure action is dispatched
yield take([ACTION_TYPES.GET_USER_DETAILS]);//provide your action type here
const locale = yield select((state) => state.common.locale);
const user = yield select((state) => state.user.user);
...