In one of the sample apps in the mixpanel-react-native repo Mixpanel is initialized like this from a separate Analytics.js file, what's the benefit of doing it this way or what's the reasoning behind doing it this way?
import {Mixpanel} from 'mixpanel-react-native';
import {token as MixpanelToken} from './app.json';
export class MixpanelManager {
static sharedInstance = MixpanelManager.sharedInstance || new MixpanelManager();
constructor() {
this.mixpanel = new Mixpanel(MixpanelToken);
this.mixpanel.init();
this.mixpanel.setLoggingEnabled(true);
}
}
export const MixpanelInstance = MixpanelManager.sharedInstance.mixpanel;
Related
Disclaimer: I'm a beginner in using Vue.js, and being used to Angular I went the Class Component way. I know that not the proper Vue.js way, but this is a fun pet project, so I elected to do it in a unusual way in order to try new things.
I have a simple component, "MyForm", written using Typescript and the Class Component Decorator.
To simulate a service, I made a Typescript class "MyService", that contain methods simulating an API call using an RxJs Observable objects with a delay. The the service function update the data contained in another class "MyDataStore", which is then read by the component to update the view.
But when the observable returns and changes the Data in the Store, it does not update the displayed data (until the next clic on the button).
The component
<template>
<v-app>
<pre>
<v-btn #click="clickBouton()">Load</v-btn>
Form counter: {{counter}}
Service counter: {{service.counter}}
Store counter : {{store.counter}}
RxJs data : {{store.data}}
</pre>
</v-app>
</template>
<script lang="ts">
import { MyDataStore } from '#/services/MyDataStore';
import { MyService } from '#/services/MyService';
import Vue from 'vue'
import Component from 'vue-class-component';
#Component
export default class MyForm extends Vue {
public counter = 0;
public store = MyDataStore;
public service = MyService;
clickBouton(){
this.counter++;
MyService.Increment()
MyService.getData();
}
}
</script>
The service
import { of, from, concatMap, delay } from 'rxjs';
import { MyDataStore } from './MyDataStore';
export class MyService {
public static counter = 0
// Update the data store with a new value every 10s
static getData(){
from(["A", "B", "C", "D"]).pipe(concatMap(item => of(item).pipe(delay(10000)))).subscribe((res: any) => {
MyDataStore.data = res;
});
}
static Increment(){
MyDataStore.counter++;
MyService.counter++
}
}
The "DataStore"
export class MyDataStore {
static data: string;
static counter = 0;
}
Any help or tutorial are welcome.
Hey In the end you get a observable. You need to subscribe a value of your component to it and descubscribe it if you destroy your component. If you are using Vue 2 you can use async pipes/filter in order to automate this process.
I found this tutorial:
https://medium.com/#p.woltschkow/a-better-practice-to-implement-http-client-in-vue-with-rxjs-c59f93bfa439
We'd like to store some site-specific config on the frontend in Spartacus.
For example: Each site (of a multisite setup) has a different Google API Key.
Right now, I've built a CONFIG_INITIALIZER factory, like the following. But with the fake scoping and all, it does not seem the correct way to do this.
import { Inject, Injectable } from '#angular/core';
import { ConfigInitializer, ConfigInitializerService, deepMerge } from '#spartacus/core';
import { StoreFinderConfig } from '#spartacus/storefinder/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { MultiSiteConfigChunk } from './multisiteconfig-tokens';
#Injectable({ providedIn: 'root' })
export class MultisiteConfigInitializer implements ConfigInitializer {
// Fake scoping :(
readonly scopes = ['all'];
readonly configFactory = () => this.resolveConfig().toPromise();
constructor(
protected configInit: ConfigInitializerService, #Inject(MultiSiteConfigChunk) private multiSiteConfig: Array<any>) {
}
protected resolveConfig(): Observable<StoreFinderConfig> {
return this.configInit.getStable('context.baseSite').pipe(
map((config) => {
const mergedConfig = deepMerge(...this.multiSiteConfig);
return mergedConfig[config.context.baseSite];
})
);
}
}
What would be the recommended way to get be able to do this?
You can check this doc first: https://sap.github.io/spartacus-docs/automatic-context-configuration/#adding-a-custom-context
If you are using automatic context configuration, you also can try this:
extends SiteContextConfigInitializer (inject your multiSiteConfig in the child class); replace SiteContextConfigInitializer using the child in providers.
replace getConfig function in child class to add the Google API Key to site-context.
In the store, I have two related models: Company and User
User
import { Model } from '#vuex-orm/core';
import { Company } from './models';
export class User extends Model {
static entity = 'users';
static fields() {
return {
company: this.belongsTo(Company, 'company_id'),
};
}
}
export default User;
Company
import { Model } from '#vuex-orm/core';
import { User } from './models';
export class Company extends Model {
// This is the name used as module name of the Vuex Store.
static entity = 'companies';
static fields() {
return {
account_manager: this.belongsTo(User, 'account_manager_id'),
};
}
}
export default Company;
To avoid dependency cycle, I closely followed the solution from https://vuex-orm.org/guide/model/single-table-inheritance.html#solution-how-to-break-cycles
and import Company and User into models.js
Models
export * from './company';
export * from './user';
Yet I still get the dependency cycle error from the linter.
I run out of ideas.
Code sample: https://github.com/mareksmakosz/vuex-orm-dependency-cycle
This is just ESLint enforcing the rule, you can't avoid it if you're using airbnb. Consider eslint:recommended if it's truly a pain.
Alternatively, if you want to keep airbnb and your models separated, I suggest dropping the imports and define your relations using entity as a string.
this.belongsTo('companies', 'company_id')
this.belongsTo('users', 'account_manager_id')
How to get the Base URL including the context for the storefront?
For example, for this URL
https://spartacus.c39j2-walkersde1-d4-public.model-t.cc.commerce.ondemand.com/electronics-spa/en/USD/OpenCatalogue/Cameras/Digital-Cameras/Digital-SLR/c/578
How do I get just
https://spartacus.c39j2-walkersde1-d4-public.model-t.cc.commerce.ondemand.com/electronics-spa/en/USD/
You can get separately the origin (https://s(...).com) and the context URL parameters (electronics-spa/en/USD/).
The origin
import { DOCUMENT } from '#angular/common';
// ...
constructor(#Inject(DOCUMENT) private document: any){}
//...
const origin = this.document.location.origin;
// "https://s(...).com"
Note: it won't work in Server Side Rendering! Please use Spartacus' injection token SERVER_REQUEST_ORIGIN then:
import { DOCUMENT } from '#angular/common';
import { PLATFORM_ID } from '#angular/core';
import { SERVER_REQUEST_OTIGIN } from '#spartacus/core';
// ...
constructor(
#Inject(DOCUMENT) private document: any,
#Inject(PLATFORM_ID) private platformId,
#Inject(SERVER_REQUEST_ORIGIN) private serverRequestOrigin
){}
// ...
let origin;
if (isPlatformServer(this.platformId)){
origin = this.serverRequestOrigin;
} else {
origin = this.document.location.origin;
}
The context URL parameters
import { Router } from '#angular/router';
// ...
constructor(private router: Router){}
// ...
const context = router.serializeUrl(router.createUrlTree(''));
// "electronics-spa/en/USD/"
Final result
const result = `${origin}/${context}`;
// "https://s(...).com/electronics-spa/en/USD/"
I have two action-script classes one is instantiated in the other. It works fine in flash professional cc but when I use the mxmlc compiler via the command prompt, it compiles a blank swf without any errors.
Monster.as
package {
import flash.net.URLRequest;
import flash.net.URLLoader;
import flash.display.Sprite;
import flash.display.Loader;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundMixer;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;
public class Monster extends Sprite {
public function Monster() {
// constructor code
var imageLoader: Loader = new Loader();
var image: URLRequest = new URLRequest("female-monster.png");
imageLoader.load(image);
addChild(imageLoader);
imageLoader.x = 0;
imageLoader.y = 0;
}
public function roar():void {
var mySound: Sound = new Sound();
mySound.load(new URLRequest("monster.mp3"));
mySound.play();
}
public function visibleMonster():void {
this.alpha = .5;
}
}
}
addMonster.as
package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
import Monster;
public class addMonster extends MovieClip {
public var monster:Monster;
public function addMonster() {
// constructor code
monster = new Monster();
addChild(monster);
monster.roar();
monster.moveMonster();
monster.visibleMonster();
}
}
}
Is it possible that there are options I need to use when running the command to compile?
Solved problem by closing Dreaweaver and Flash applications which were using the file I was trying to run mxmlc compiler to compile the as file.