i want to share data between components, so im implemented a Service which has an EventEmitter.
My Service looks like this:
@Injectable()
export class LanguageService {
constructor() {
this.languageEventEmitter = new EventEmitter();
this.languages = [];
this.setLanguages();
}
setLanguages() {
var self = this;
axios.get('/api/' + api.version + '/' + api.language)
.then(function (response) {
_.each(response.data, function (language) {
language.selected = false;
self.languages.push(language);
});
self.languageEventEmitter.emit(self.languages);
})
.catch(function (response) {
});
}
getLanguages() {
return this.languages;
}
toggleSelection(language) {
var self = this;
language.selected = !language.selected;
self.languages.push(language);
self.languageEventEmitter.emit(self.languages);
}
}
I have to components, which are subscribing to the service like this:
self.languageService.languageEventEmitter.subscribe((newLanguages) => {
_.each(newLanguages, function (language) {
self.updateLanguages(language);
});
});
When both components are loaded, the language arrays get filled as i wish.
This is the first component:
export class LanguageComponent {
static get parameters() {
return [[LanguageService]];
}
constructor(languageService) {
var self = this;
this.languageService = languageService;
this.languages = [];
this.setLanguages();
}
setLanguages() {
var self = this;
self.languageService.languageEventEmitter.subscribe((newLanguages) => {
_.each(newLanguages, function (language) {
self.updateLanguages(language);
})
});
}
updateLanguages(newLanguage) {
var self = this;
if (!newLanguage) {
return;
}
var match = _.find(self.languages, function (language) {
return newLanguage._id === language._id;
});
if (!match) {
self.languages.push(newLanguage);
}
else {
_.forOwn(newLanguage, function (value, key) {
match[key] = value;
})
}
toggleLanguageSelection(language) {
var self = this;
self.languageService.toggleSelection(language)
}
}
When LanguageComponent executes the function toggleLanguageSelection() which triggered by a click event, the other component, which subscribes like this:
self.languageService.languageEventEmitter.subscribe((newLanguages) => {
_.each(newLanguages, function (language) {
self.updateLanguages(language);
})
});
doesn't get notfiefied of the change. I think this happens because both component get a different instance of my LanguageService, but i'm not sure about that. I also tried to create a singleton, but angular'2 di doesn't work then anymore. What is the reason for this issue and how can i solve this ?
You need to define your shared service when bootstrapping your application:
bootstrap(AppComponent, [ SharedService ]);
and not defining it again within the providers
attribute of your components. This way you will have a single instance of the service for the whole application. Components can leverage it to communicate together.
This is because of the "hierarchical injectors" feature of Angular2. For more details, see this question: