Share Data between Services in angular js 1.4 - angularjs

Sample URLs:
/users/api/getUser
/users/api/addUser
/users/api/deleteUser/{userId}
I want to store the common path(/users/api) in a global variable and pass it to each service so as to concate it with Request URL before calling REST endpoint. I have created one class and stored url prefix. But I am not able to get its value in Service. Below is the code snippet.
import CommonVariables from './commonVariables';
class UserService {
/*#ngInject*/
constructor($rootScope, Rest){
Object.assign(this, {$rootScope, Rest});
}
getUsers() {
console.log("commonVariables.getBaseURL: ", CommonVariables.baseURL);
console.log("commonVariables.getBaseURL: ", CommonVariables.getBaseURL());
return this.Rest.one("/users/api/getUser").get();
}
addUserDetails(request) {
return this.Rest.one("/users/api/addUser").customPOST(request);
}
}
export default UserService
CommonVariable
class CommonVariables {
/*#ngInject*/
constructor($rootScope){
Object.assign(this, {$rootScope});
let vm = this;
vm.baseURL = "/users/api";
}
getBaseURL() {
console.log("getBaseURL called");
return "/users/api";
}
}
export default CommonVariables

Change export default CommonVariables to export default new CommonVariables();

Related

Angular/Typescript - Get data from array services

I'm trying to retrieve data from an array in my services through a get function. I'm aware that I can use the .filter or .find functions, however, I'm really getting confused about the execution and after many tries I was unable to retrieve the information. I can understand that this may considered a very basic question but I'm fairly new to this. Any help would be really appreciated.
tracker-data.ts:
export class TrackerData {
entry?: number;
exit?: number;
clicks: string[] = [];
url?: string;
public get clickCount(): number
{ return this.clicks.length; }
}
tracker.service.ts
import { Injectable } from '#angular/core';
import { TrackerData } from '../modules/tracker-data';
#Injectable({
providedIn: 'root'
})
export class TrackerService {
websiteData: TrackerData[] = [];
public count = 0;
constructor() { }
addTrackerData(trackerData: TrackerData): void {
this.websiteData.push(trackerData);
}
getData() {
return this.websiteData;
}
}
summary.component.ts (where the data should be displayed)
import { Component, OnInit } from '#angular/core';
import { TrackerService } from 'src/app/services/tracker.service';
import { TrackerData } from 'src/app/modules/tracker-data';
#Component({
selector: 'app-summary',
templateUrl: './summary.component.html',
styleUrls: ['./summary.component.scss']
})
export class SummaryComponent implements OnInit {
websiteData: TrackerData[] = [];
constructor(
private trackerService: TrackerService,
) { }
ngOnInit(): void {
}
getData(){
this.websiteData = this.trackerService.getData();
console.log(this.websiteData);
}
}
You are not receiving the data in the log because the function isn't being called anywhere in the code and it's also not being used in any of the lifecycle events. To initialize data from a service it is common to call functions from services in the ngOnInit lifeCycle event. This seems to be what you are trying to do so you should call the trackerService.getData() function there.
It would look something like this:
ngOnInit(): void {
this.websiteData = this.trackerService.getData();
console.log(this.websiteData);
}
There are more ways to call the function, it is possible to call the function in the constructor(when the component is being created) but this is not standard practice. Functions can also be triggered when an event occurs on your webpage, for example when a user clicks on a button.
I suggest you look more into the Angular documentation though because it's very good and explains all the basics in better detail: https://angular.io/docs

Meteor Collection find()/fetch() working sometimes

I started working with meteor which seems to be good for my use, a problem occurred where I get my documents only 9/10 times. I think I implemented something wrong.
I use Angular 1.5 and Typescript
My collection gets created in the lib folder at /
import { Mongo } from 'meteor/mongo';
export const Locations= new Mongo.Collection('locations');
then the collection gets imported to my service
import {app} from '../../js/lib/app';
import {Locations} from '../../../lib/collections';
export class LocationsService {
locations: any;
constructor(){
console.log('Constructor called');
this.locations = Locations
.find({})
.fetch();
console.log('documents loaded');
console.log(this.locations);
}
public createLocation(any:any){
Locations.insert(any);
}
public updateLocation(identity:any, modifier:any){
Locations.update(identity,modifier);
}
}
app.service('locationsService', LocationsService);
Here are the console.logs from 3 different page refreshes:
It looks like the amount of docs I get is totally random.
Here is some code that will help you. It uses the "resolve" feature of ui-router to hold up loading of the page until data is loaded. In this case there are two things being resolved:
User record
Elders record
The second one needs an "elderid" from users.profile in order to find an elder record.
function config($locationProvider, $urlRouterProvider, $stateProvider) {
'ngInject';
$stateProvider
.state('member.calendar', {
url: '/calendar',
template: "<membercalendar></membercalendar>",
resolve: {
currentUser: ($q) => {
var deferred = $q.defer();
Meteor.autorun(function () {
if (!Meteor.loggingIn()) {
if (Meteor.user() == null) {
deferred.reject('AUTH_REQUIRED');
} else {
deferred.resolve(Meteor.user());
}
}
});
return deferred.promise;
},
elder: ($q) => {
var deferred = $q.defer();
Meteor.autorun(function () {
if (!Meteor.loggingIn()) {
if (Meteor.user() == null) {
deferred.reject('AUTH_REQUIRED');
} else {
deferred.resolve(Elders.find({_id: Meteor.user().profile.elderid}));
}
}
});
return deferred.promise;
}
}
});
}
This works well if you want the data to be loaded fully before the page loads. If you don't mind an asynchronous update to the page, you can use getReactively to make a helper run once the data has resolved. I can give you example code for that too if you like.
My new Service simply subscribes
export class LocationsService {
locations:any;
constructor(){
console.log('Constructor called');
//Subscribe to a collection//localStorage.getItem('ID')
Meteor.subscribe('locations', 2223 );
this.locations = Locations;
console.log('documents loaded');
}
public createLocation(any:any){
Locations.insert(any);
}
public updateLocation(identity:any, modifier:any){
Locations.update(identity,modifier);
}
}
app.service('locationsService', LocationsService);
In my controller i simply add the fetching of my documents in the Tracker.
import {app} from '../../js/lib/app';
import {LocationsService} from './LocationsService';
import {Tracker} from 'meteor/tracker';
export class LocationsController {
static $inject = ['locationsService','$reactive','$scope'];
public $reactive: any;
public $scope: any;
public locations: any[];
constructor(private locationsService: LocationsService, $reactive:any, $scope:any){
this.locationsService = locationsService;
this.$reactive = $reactive;
this.$scope = $scope;
$reactive(this).attach(this.$scope);
Tracker.autorun(() => {
//console.log('autorun');
this.locations = locationsService.locations.find({}).fetch();
console.log(this.locations)
});
}
public createLocation(location:any){
console.log('Locations does what it should');
console.log(location);
this.locationsService.createLocation(location);
}
public updateLocation(location:any, modifier:any){
this.locationsService.updateLocation(location._id,modifier)
}
}
app.controller('locationsController', LocationsController);
The only problem I have now is that the modell updates like a charm but not the view when I create new locations. The autorun works and the new location gets saved in my collection but I see it only if I reload. But that one is low priority for me.

Sharing data between controllers in Typescript | Angular JS

I have worked with angular js with javascript where as I know I can able to create service to share data . I am new to typescript it would be great if anyone could help us to understand how to create service in typescript to share data between controllers
The below sample service is called from the controller. Even I changed the service values when I tried redirect from other page the value is not getting changed it is having the default values. Though I am using the syntax
angular.module("app").service(...)
I believe the service is creating new instance when the controller is loaded.
export class sharedData {
public getMyProperty(): boolean {
return this._myProperty;
}
public setMyProperty(value) {
this._myProperty= value;
}
private _myProperty: boolean = false;
}
angular.module("app")
.service("sharedData", App.RfiDetail.sharedData);
I have tried with function also , but its not working
export function sharedFactory() {
return {
setStatus: setStatus,
getSuccess: getSuccess
};
function setStatus(value) {
this._myProperty = value;
}
function getSuccess() {
return this._myProperty;
}
}
angular.module(App.Constants.Modules.app)
.factory("sharedFactory", App.RfiDetail.sharedFactory);

How to pass data from AngularJS form to struts 2 action class?

Here I am developing shopping cart. This is my AngularJS controller. This method use to send data to action
class using $http.post method
angular.module("sportsStore")
.constant("dataUrl", "angularAction")
.constant("orderUrl", "angularSaveAction")
.controller("sportsStoreCtrl", function ($scope, $http, $location,
dataUrl, orderUrl, cart) {
enter code here`$scope.data = {
};
$scope.sendOrder = function (shippingDetails) {
var order = angular.copy(shippingDetails);
order.products = cart.getProducts();
console.log(order);--------------(1)
$http.post(orderUrl, order)
.success(function (data) {
//$scope.items=data;
$scope.data.orderId = data.id;
cart.getProducts().length = 0;
console.log(data);---------------(2)
})
.error(function (error) {
$scope.data.orderError = error;
}).finally(function () {
$location.path("/complete");
});
}});
Using (1) console.log i confirm all form data and shopping cart detail stoed array.But (2) console log is Null
This is my Action class
package com.ai.action;
import com.ai.model.PersonData;
import com.ai.model.Product;
import com.ai.model.ProductOrder;
import com.ai.model.Village;
import com.ai.service.PersonService;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import org.apache.struts2.dispatcher.mapper.ActionMapping;
import org.slf4j.Logger;
public class OrderAction extends
ActionSupport implements ModelDriven<ProductOrder> {--------------(1)
private Map session = ActionContext.getContext().getSession();
private Logger logger = LoggerFactory.getLogger(AngularAction.class);
private List<ProductOrder> order;-------------(2)
private ProductOrder productOrder;
#Autowired
private PersonService personService;
public String execute()
{
getOrder();
logger.info("this method ic" ,order);
//personService.save(personService);----------(3)
return SUCCESS;
}
public List<ProductOrder> getOrder() {
return order;
}
public void setOrder(List<ProductOrder> order) {
this.order = order;
}
#Override
public ProductOrder getModel() {
return productOrder;
}
}
How I get form data
Can I use
ModleDriven(1) or
List array(2) or any method. I want save this form data in mysql database using hibernate(3).please help me....
How I get form data
Can I use
ModleDriven(1) or
List array(2) or any method. I want save this form data in mysql database using hibernate(3).please help me....

How can I define an AngularJS service using a TypeScript class that doesn't pollute the global scope?

I am using AngularJS and TypeScript. I want to implement an AngularJS service using a Typescript class, like this:
class HelloService {
public getWelcomeMessage():String {
return "Hello";
}
}
angular.module('app.services.helloService', []).factory('helloService', () => {
return new HelloService();
});
This compiles to the following javascript code:
var HelloService = (function () {
function HelloService() {
}
HelloService.prototype.getWelcomeMessage = function () {
return "Hello";
};
return HelloService;
})();
angular.module('app.services.helloService', []).factory('helloService', function () {
return new HelloService();
});
This pollutes the global namespace with the variable HelloService, which I obviously don't want. (Using Chrome's console I verified that HelloService was an object.) How can I solve/avoid this problem?
I tried the obvious:
angular.module('app.services.helloService', []).factory('helloService', function () {
class HelloService { ...}
return new HelloService();
});
but that gives me a compile error ("Unexpected token; 'statement' expected.").
One possible solution I can think of is using TypeScript's import and export somehow, which in turn will use RequireJS. This probably will wrap the HelloService within a define function, thus avoiding pollution of the global scope with HelloService. However, I don't want to use RequireJS in my AngularJS application for now, as I think AngularJS is good enough for my use, and it adds complexity.
So, my question is, how can I define an AngularJS service using a TypeScript class that doesn't pollute the global scope?
2016-05-06: New example using ES6-style modules
The static $inject array and constructor remain unchanged from the previous example.
The only change is to split the classes into multiple files and use ES6 modules to pull in the class definitions.
/lib/HelloService.ts:
export class HelloService {
public getWelcomeMessage():String {
return "Hello from HelloService";
}
}
/lib/AnotherService.ts:
import {HelloService} from './HelloService';
/**
* Service that depends on HelloService.
*/
export class AnotherService {
// Define `HelloService` as a dependency.
static $inject = ['HelloService'];
constructor(
// Add the parameter and type definition.
public HelloService: HelloService
){}
public getWelcomeMessage():String {
// Access the service as: `this.HelloService`
// Enjoy auto-completion and type safety :)
var helloMsg = this.HelloService.getWelcomeMessage();
return "Welcome from AnotherService, " + helloMsg;
}
}
/index.ts:
// Using the services.
import {HelloService} from './lib/HelloService';
import {AnotherService} from './lib/AnotherService';
angular.module('HelloApp', [])
.service('HelloService', HelloService)
.service('AnotherService', AnotherService)
.run(['AnotherService', function(AnotherService: AnotherService){
console.log(AnotherService.getWelcomeMessage());
}]);
Previous answer: using namespaces
Building from Steve Fenton's answer:
To allow dependency injection, add a static $inject array on your class.
See the Angular $injector documentation on how the $inject array works.
The dependencies will be injected into your constructor in the order given by the array (and makes it work with minification).
Dependency Injection Example:
namespace MyModule {
/**
* Angular Service
*/
export class HelloService {
public getWelcomeMessage():String {
return "Hello from HelloService";
}
}
/**
* Service that depends on HelloService.
*/
export class AnotherService {
// Define `HelloService` as a dependency.
static $inject = ['HelloService'];
constructor(
// Add the parameter and type definition.
public HelloService: MyModule.HelloService
){}
public getWelcomeMessage():String {
// Access the service as: `this.HelloService`
// Enjoy auto-completion and type safety :)
var helloMsg = this.HelloService.getWelcomeMessage();
return "Welcome from AnotherService, " + helloMsg;
}
}
}
// Using the services.
angular.module('app.services.helloService', [])
.service('HelloService', MyModule.HelloService)
.service('AnotherService', MyModule.AnotherService)
.run(['AnotherService', function(AnotherService: MyModule.AnotherService){
console.log(AnotherService.getWelcomeMessage());
}]);
I should provide what I actually ended doing:
module MyModule {
export class HelloService {
public getWelcomeMessage():String {
return "Hello";
}
}
angular.module('app.services.helloService', []).factory('helloService', () => {
return new HelloService();
});
}
In this way I can use
return new HelloService();
instead of
return new MyModule.HelloService();
I have two solutions, the first gives you class-based syntax, the second leaves absolutely nothing in the global scope...
You could compromise slightly by only adding a single handle to the global scope (this really applies if you have multiple classes that you want to avoid placing in the global scope as currently you only have one class).
The following code leaves only the module in the global scope.
module MyModule {
export class HelloService {
public getWelcomeMessage():String {
return "Hello";
}
}
export class AnotherService {
public getWelcomeMessage():String {
return "Hello";
}
}
}
angular.module('app.services.helloService', []).factory('helloService', () => {
return new MyModule.HelloService();
});
angular.module('app.services.anotherService', []).factory('anotherService', () => {
return new MyModule.AnotherService();
});
Alternatively, to leave not a single thing in global scope, you could avoid the class syntax and use "plain old JavaScript":
angular.module('app.services.helloService', []).factory('helloService', () => {
var HelloService = (function () {
function HelloService() {
}
HelloService.prototype.getWelcomeMessage = function () {
return "Hello";
};
return HelloService;
})();
return new HelloService();
});
This is the method that I'm following:
module HelperServices {
export class helloService {
sayHelloWorld: () => string;
constructor() {
this.sayHelloWorld = () => {
return "Hello World";
}
}
}
}
As simple as that..

Resources