SmartEditService.isLaunchedInSmartEdit() is always returns null - spartacus-storefront

I have Spartacus storefront app.
Spartacus version is 3.2.2.
I have the requirement to check if the page is loaded in smart edit or not.
For that I tried to use this.smartEditService.isLaunchedInSmartEdit() but it always returns null value.
Please help me to find solution.
Below is my sample service code.
import { Product, ProductService, RoutingService, CmsService, SmartEditService } from '#spartacus/core';
import { Observable } from 'rxjs';
#Injectable({
providedIn: 'root',
})
export class CurrentProductService {
constructor(
private smartEditService: SmartEditService
) {
}
getProduct(): Observable<Product> {
if (this.smartEditService && this.smartEditService.isLaunchedInSmartEdit()) {
return false
}
return true;
}
}

From 3.2, the SmartEditModule is deprecated. You can either import the deprecated SmartEditModule (from core) in your app, or use the SmartEditService from #spartacus/smartedit lib.

Related

How to handle types for injected properties in Vue Composition API - Typescript

import firebase from 'firebase'
import Vue from 'vue'
/* This file simply imports the needed types from firebase and forwards them */
declare module 'vue/types/vue' {
interface Vue {
$fireStore: firebase.firestore.Firestore
$fireDb: firebase.database.Database
$fireFunc: firebase.functions.Functions
$fireStorage: firebase.storage.Storage
$fireAuth: firebase.auth.Auth
$fireMess: firebase.messaging.Messaging
}
}
In normal typescript project with Vue 2, we can do this. But when use Composition API, how I can inject the properties like this in root on function setup(_, { root})?
So I cant use with root.$fireStore...
Now, I must use it with the any type like (root as any).$fireStore. So hope anyone can help my team. We are working on a project with Nuxt Composition now.
it's kind of the same in vue 3 but not the same module
declare module '#vue/runtime-core' {
interface ComponentCustomProperties {
$fireStore: firebase.firestore.Firestore
$fireDb: firebase.database.Database
$fireFunc: firebase.functions.Functions
$fireStorage: firebase.storage.Storage
$fireAuth: firebase.auth.Auth
$fireMess: firebase.messaging.Messaging
}
}
How about creating a composable for firebase?
import firebase from 'firebase'
export default function useFirebase() {
return {
fireStore: firebase.firestore.Firestore
fireDb: firebase.database.Database
fireFunc: firebase.functions.Functions
fireStorage: firebase.storage.Storage
fireAuth: firebase.auth.Auth
fireMess: firebase.messaging.Messaging
};
};
And then use it in your setup() of the component:
export default defineComponent({
setup() {
const {fireStore, fireDb, fireFunc, fireStorage, fireAuth, fireMess} = useFirebase();
}
});
Yes, after a few days, I reached out the temporary solution for this. Just add a nuxt.d.ts or your types folder like this. So you can use $apolloHelpers in your Vue Instances and Middleware...
import { SetupContext } from '#vue/composition-api'
/**
* #description Define type for $apolloHelpers --> copy from Apollo module --> inject Apollo Helpers
* #docs https://github.com/nuxt-community/apollo-module/blob/master/lib/templates/plugin.js#L141
*/
declare module '#nuxt/types' {
interface Context {
$apolloHelpers: {
onLogin(token, apolloClient, cookieAttributes, skipResetStore = false)
onLogout(apolloClient, skipResetStore = false)
getToken(tokenName?: string)
}
}
interface NuxtAppOptions {
$apolloHelpers: {
onLogin(token, apolloClient, cookieAttributes, skipResetStore = false)
onLogout(apolloClient, skipResetStore = false)
getToken(tokenName?: string)
}
}
}
declare module 'vue/types/vue' {
interface Vue {
$apolloHelpers: {
onLogin(token, apolloClient, cookieAttributes, skipResetStore = false)
onLogout(apolloClient, skipResetStore = false)
getToken(tokenName?: string)
}
}
}
I don't know if it will help you, but there is root.$store.$fireAuth
insert #nuxt/types in your tsconfig.json and the types will work

Nuxtjs using Vuex-module-decorator doesn't wordk

I want to use my vuex modules as classes to make my code more clean and readable. I used the section (Accessing modules with NuxtJS) at the bottom of this document: https://github.com/championswimmer/vuex-module-decorators/blob/master/README.md
I've searched for the solution for almost 3 days and tried out this link:
vuex not loading module decorated with vuex-module-decorators
but, it didn't work.
Also, I used getModule directly in the component like the solution in this issue page: https://github.com/championswimmer/vuex-module-decorators/issues/80
import CounterModule from '../store/modules/test_module';
import { getModule } from 'vuex-module-decorators';
let counterModule: CounterModule;
Then
created() {
counterModule = getModule(CounterModule, this.$store);
}
Then, accessing method elsewhere
computed: {
counter() {
return counterModule.getCount
}
}
it didn't work for me!
This is my Module in store folder in Nuxtjs project:
import { ICurrentUser } from '~/models/ICurrentUser'
import { Module, VuexModule, Mutation, MutationAction } from 'vuex-module-decorators'
#Module({ stateFactory: true, namespaced: true, name: 'CurrentUserStore' })
export default class CurrentUser extends VuexModule {
user: ICurrentUser = {
DisplayName: null,
UserId: null,
};
#Mutation
setUser(userInfo: ICurrentUser) {
this.user = userInfo;
}
get userInfo() {
return this.user;
}
}
In index.ts file in sore folder:
import { Store } from 'vuex'
import { getModule } from 'vuex-module-decorators'
import CurrentUser from './currentUser'
let currentUserStore: CurrentUser
const initializer = (store: Store<any>): void => {
debugger
currentUserStore = getModule(CurrentUser, store)
}
export const plugins = [initializer]
export {
currentUserStore,
}
I think the problem stems from this line:
currentUserStore = getModule(CurrentUser, store)
currentUserStore is created as object but properties and methods are not recognizable.
when I want to use getters or mutation I get error. For instance, "unknown mutation type" for using mutation
Probably several months late but I struggled with a similar issue, and eventually found the solution in https://github.com/championswimmer/vuex-module-decorators/issues/179
It talks about multiple requirements (which are summarised elsewhere)
The one that relates to this issue is that the file name of the module has to match the name you specify in the #Module definition.
In your case, if you rename your file from currentUser to CurrentUserStore' or change the name of the module toCurrentUser`, it should fix the issue.

Ionic 4 Not support Events?

Im using Event fucntion to publish some data in app. But its not working in ionic 4. I need to know ionic 4 support Events or not?
import { Events } from '#ionic-angular';
// Module not found: Error: Can't resolve '#ionic-angular'
You can use #angular/Events
//MyEvents Service Page
import { Injectable } from '#angular/core';
import { Subject, Observable } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class EventsService {
constructor() { }
private subject = new Subject<any>();
sendMessage(text){
this.subject.next(text);
}
getMessage():Observable<any>{
return this.subject.asObservable();
}
}
//Page for sendMessage
constructor(private events: EventsService) {
this.events.sendMessage({'created':1}); //send message key-value format
}
//Page for getMessage
subscription: Subscription;
constructor(private events: EventsService) {
this.subscription = this.events.getMessage().subscribe(text => {
console.log(text.created);
})
}
Below solution is working in ionic v4
import { Events } from '#ionic/angular';
constructor(private events: Events) {
events.subscribe('notificationLength', notilen => {
//TO DO`enter code here`
})
}
// Publish the events where ever you want
this.events.publish('notificationLength', this.NotificationList.length)
The problem was in the version. When I updated to the latest patch of version 4, it was working.
npm i #ionic/angular#4.11.10

How to use Toasted inside an export default {}

I'm trying to use the package Toasted but I'm having a hard time understading how to use it.
I have a package called TreatErrors.js and I call this package to handle all errors from my application based on HTTP code returned by API a restfull API.
TreatErrors.js
import toasted from 'vue-toasted';
export default {
treatDefaultError(err){
let statusCode = err.response.status;
let data = err.response.data;
for(let field in data.errors){
if (data.errors.hasOwnProperty(field)) {
data.errors[field].forEach(message => {
toasted.show(message);
})
}
}
if(statusCode === 401){
toastr.error('Your token has expired. Please logout and login again to retrieve a new token');
}
return null;
},
}
and I'm tryin to call Toasted from within this package but I'm getting vue_toasted__WEBPACK_IMPORTED_MODULE_2___default.a.show is not a function. Any idea how I can use this Toasted inside of my own defined package?
The vue-toasted plugin must be registered with Vue first:
import Toasted from 'vue-toasted';
Vue.use(Toasted); // <-- register plugin
Then, your module could use it via Vue.toasted.show(...):
// TreatErrors.js
export default {
treatDefaultError(err) {
Vue.toasted.show(err.message);
}
}
And your Vue components could also use it via this.$toasted.show(...):
// Foo.vue
export default {
methods: {
showError(err) {
this.$toasted.show(err.message);
}
}
}

How to use combineLatest and takeUntil rxjs operators in Angular 5

I see that in Angular 5 one should be using rxjs operators differently and importing from 'rxjs/operators' but I'm a little unclear on how it is supposed to work. I have something like:
import { Observable } from 'rxjs/Observable';
import { combineLatest, takeUntil } from 'rxjs/operators';
#Component({ ... })
export class FooComponent implements OnInit, OnDestroy {
constructor(private route: ActivatedRoute) {}
ngOnInit() {
this.route_data = Observable.combineLatest(this.route.params, this.route.data,
(params, data) => ({params,data}));
this.route_data_sub = this.route_data.takeUntil(this.destroyed$).subscribe(
(params_and_data) => {
...
}
}
...
}
but I'm getting Observable.combineLatest is not a function errors. If I add the combineLatest operator the old way it works for combineLatest, but then takeUntil is now not found. How is this supposed to be done with Angular 5?
I have quite a bit of rxjs code all over the app and don't know how it is supposed to be rewritten or how to change the imports. Does everything have to be rewritten with .pipe() now?
You should import combileLatest use
import { combineLatest } from 'rxjs/observable/combineLatest';
For takeUntil
import { takeUntil } 'rxjs/operators';
I found that information:
combineLatest
takeUntil
#Mad Dandelion has the right answer but I figured it's worth showing what it looks like putting it together for anyone running across the same thing. You do have to pipe things like takeUntil. It's a bit of a pain to go through a large app and find all these spots but doesn't take that long. Doesn't look that bad either and has all the benefits in https://github.com/ReactiveX/rxjs/blob/master/doc/pipeable-operators.md under "why".
import { Observable } from 'rxjs/Observable';
import { combineLatest } from 'rxjs/observable/combineLatest';
import { takeUntil } from 'rxjs/operators';
#Component({ ... })
export class FooComponent implements OnInit, OnDestroy {
constructor(private route: ActivatedRoute) {}
ngOnInit() {
this.route_data = combineLatest(this.route.params,
this.route.data,
(params, data) => ({params,data})
);
this.route_data_sub = this.route_data
.pipe(takeUntil(this.destroyed$)) //<-- pipe()
.subscribe((params_and_data) => {
...
})
}
...
}
Also in my case I had some stale dlls serving the older rxjs (https://webpack.js.org/plugins/dll-plugin/) so if you run into something that looks like your Observables don't have the pipe property, you might want to make sure the dlls are building properly if you use that.