I am using gulp to run and build to run my application. I am getting file contents using $http service in my index.js file and then setting value of a variable like
window.variablex = "http://localhost:8080/appname".
here is how I am doing it (in index.js)
(function ()
{
'use strict';
angular
.module('main')
.controller('IndexController', IndexController);
function IndexController($http){
$http.get('conf/conf.json').success(function(data){
window.variable = data.urlValue;
}).error(function(error){
console.log(error);
});
}
});
And I've created a factory to call the rest APIs of my backend application like
(function(){
'use strict';
angular
.module('main')
.factory('testService',['$resource',testService]);
function agentService($resource){
var agents = $resource('../controller/',{id:'#id'},
{
getList:{
method:'GET',
url:window.variable+"/controller/index/",
isArray:false
}
});
Now, I except a rest call to made like
http://localhost:8080/appname/controller
But it always sends a call like http://undefined/appname/controller which is not correct.
I can get the new set value anywhere else, but this value is not being set in resource service objects somehow.
I am definitely missing something.
Any help would be much appreciated
As you are using Gulp, I advise you to use gulp-ng-config
For example, you have your config.json:
{
"local": {
"EnvironmentConfig": {
"api": "http://localhost/"
}
},
"production": {
"EnvironmentConfig": {
"api": "https://api.production.com/"
}
}
}
Then, the usage in gulpfile is:
gulp.task('config', function () {
gulp.src('config.json')
.pipe(gulpNgConfig('main.config', {
environment: 'production'
}))
.pipe(gulp.dest('.'))
});
You will have this output:
angular.module('myApp.config', [])
.constant('EnvironmentConfig', {"api": "https://api.production.com/"});
And then, you have to add that module in your app.js
angular.module('main', [ 'main.config' ]);
To use that variable you have to inject in your provider:
angular
.module('main')
.factory('testService', ['$resource', 'EnvironmentConfig', testService]);
function agentService($resource, EnvironmentConfig) {
var agents = $resource('../controller/', {id: '#id'},
{
getList: {
method: 'GET',
url: EnvironmentConfig + "/controller/index/",
isArray: false
}
});
}
#Kenji Mukai's answer did work but I may have to change configuration at run time and there it fails. This is how I achieved it (in case anyone having an issue setting variables before application gets boostrap)
These are the sets that I followed
Remove ng-app="appName" from your html file as this is what causing problem. Angular hits this tag and bootstraps your application before anything else. hence application is bootstratped before loading data from server-side (in my case)
Added the following in my main module
var injector = angular.injector(["ng"]);
var http = injector.get("$http");
return http.get("conf/conf.json").then(function(response){
window.appBaseUrl = response.data.gatewayUrl
}).then(function bootstrapApplication() {
angular.element(document).ready(function() {
angular.bootstrap(document, ["yourModuleName"]);
});
});
This will load/set new values everytime you refresh your page. You can change conf.json file even at runtime and refreshing the page will take care of updating the values.
Related
I have an AngularJS web application. Everything works fine but I've noticed this error during start up on the console log:
Basically it complains about a module not being found, a module with an empty name?
Module '' is not available! You either misspelled the module name or
forgot to load it. If registering a module ensure that you specify the
dependencies as the second argument.
the exception creates automatically a URL to the online help, of course the p0 parameter is emtpy
https://docs.angularjs.org/error/$injector/nomod?p0=
Inspecting further if I follow the stack trace I end up in this file here (it's very long, so for convenience I'll crop it
angular.module("").run(['$templateCache', function(a) { a.put('/app/components/upload/upload.html', '<et-top-nav></et-top-nav><div class="uploadPage"><div style="margin-top:3.7em"><et-uploader></et-uploader>....
The parameter for the module() function looks to be an empty string
The name of the app is "app", not an empty string
any clue on what's going on here?
EDIT
App initialization:
(function() {
angular
.module("app", ["ngNewRouter", "ngSanitize", "ngFileUpload", "ngToast", "ngAnimate", "ui.bootstrap"])
.config(["$locationProvider", configureLocationProvider])
.config(["$httpProvider", configureHttpProvider])
.config(["ngToastProvider", configureToastProvider])
.controller("AppController", ["$router", "$rootScope", "onChartUrlChange", appController])
.run(["onWindowResize", setup]);
function appController($router, $rootScope, onChartUrlChange) {
$router.config([
{ path: "/", components: {"default":"chartPicker"} },
{ path: "/upload", components: {"default":"upload"} },
{ path: "/batch/:groupId", components: {"default":"chart"} }
]);
// AngularJS doesn't update components on frag change, so we do it ourselves
$rootScope.$on("$locationChangeSuccess", function() {
onChartUrlChange.updateChart();
});
$rootScope.$on("$zoomUrlChanged", function() {
onChartUrlChange.updateChart();
});
}
The template file generated by Broccoli doesn't include the name of the app (which sould be "app")
angular.module("").run(['$templateCache', function(a) { a.put('/app/components/chart-picker/chart-pi...
and this is causing the exception
First, I try to make a custom visualization in Kibana with learning here.
Then, I want my custom visualization to display like the clock how many hits my elasticsearch index has dynamically .
So, I changed some codes in above tutorial but they don't work.
Chrome Devtools tells says Error: The elasticsearch npm module is not designed for use in the browser. Please use elasticsearch-browser
I know I had better use elasticsearch-browser perhaps.
However, I want to understand what is wrong or why.
public/myclock.js
define(function(require) {
require('plugins/<my-plugin>/mycss.css');
var module = require('ui/modules').get('<my-plugin>');
module.controller('MyController', function($scope, $timeout) {
var setTime = function() {
$scope.time = Date.now();
$timeout(setTime, 1000);
};
setTime();
var es = function(){
var elasticsearch = require('elasticsearch');
var client = new elasticsearch.Client({
host: 'localhost:9200',
log: 'trace'
});
client.search({
index: 'myindex',
}).then(function (resp) {
$scope.tot = resp.hits.total;
}, function (err) {
console.trace(err.message);
});
};
es();
});
function MyProvider(Private) {
...
}
require('ui/registry/vis_types').register(MyProvider);
return MyProvider;
});
public/clock.html
<div class="clockVis" ng-controller="MyController">
{{ time | date:vis.params.format }}
{{tot}}
</div>
Thank you for reading.
Looks like the controller in angularjs treats the elasticsearch javascript client as if it was accessing from the browser.
To elude this, one choice will be by building Server API in index.js and then make kibana access to elasticsearch by executing http request.
Example
index.js
// Server API (init func) will call search api of javascript
export default function (kibana) {
return new kibana.Plugin({
require: ['elasticsearch'],
uiExports: {
visTypes: ['plugins/sample/plugin']
},
init( server, options ) {
// API for executing search query to elasticsearch
server.route({
path: '/api/es/search/{index}/{body}',
method: 'GET',
handler(req, reply) {
// Below is the handler which talks to elasticsearch
server.plugins.elasticsearch.callWithRequest(req, 'search', {
index: req.params.index,
body: req.params.body
}).then(function (error, response) {
reply(response);
});
}
});
}
});
}
controller.js
In the controller, you will need to call GET request for above example.
$http.get( url ).then(function(response) {
$scope.data = response.data;
}, function (response){
$scope.err = "request failed";
});
In my case, I used url instead of absolute or relative path since path of dashboard app was deep.
http://[serverip]:5601/iza/app/kibana#/dashboard/[Dashboard Name]
*
Your here
http://[serverip]:5601/iza/[api path]
*
api path will start here
I used this reference as an example.
The following code works:
angular.module("appname").value("RavenConfig", {
dsn: "key",
config: {
maxMessageLength: 1000,
},
});
The following code does not work:
RavenConfig = function($window) {
return {
dsn: "key",
config: {
maxMessageLength: 1000,
},
}
};
RavenConfig.$inject = ["$window"];
angular.module("appname").value("RavenConfig", RavenConfig);
I get Error: Raven has not been configured.
Can you try this:
angular.module('appname').value('RavenConfig', RavenConfig);
function RavenConfig($window) {
return {
dsn: "key",
config: {
maxMessageLength: 1000
}
}
};
RavenConfig.$inject = ['$window'];
You can't. Values are set up during the configuration/bootstrapping process, to be made available to services later. You will need to go through the provider. See this related question.
value is intended for constants. It is a wrapper around factory service with dummy factory function.
Use factory for services that have dependencies:
angular.module("appname").factory("RavenConfig", RavenConfig);|
Using ui.router this successfully directs me to the proper view and properly retrieves the data from my factory:
.state('calendar', {
url: '/calendar',
templateUrl: 'templates/calendar.html',
controller: 'calendarCtrl',
resolve: {
workoutData: ['WorkoutData', function(WorkoutData){ // USING A FACTORY (workoutDataFct.js)
return WorkoutData.get();
}]
}
})
but I now want to pull in data from another factory but I can't seem to just add a new factory like this:
resolve: {
workoutData: ['WorkoutData', function(WorkoutData){
return WorkoutData.get();
}],
exercises: ['Exercises', function(Exercises){ // USING FACTORY (exercisesFct.js)
return Exercises.get();
}]
}
My factory, exerciseFct.js, is included in my index.html just like workoutDataFct.js and I included the exercises the dependency in my controller calendarCtrl just like I added the workoutData dependency. (am I forgetting to do something?)
I don't get and console errors and but I am not routed to the calendar view. This makes me think that the resolve: is failing. How do I fix this?
To make things clear here are the available options in your case.
Option 1:
Wait for all promises to finish with $q.all.
resolve: {
delayedData: function($q, WorkoutData, Exercises) {
var WorkoutData = WorkoutData.get();
var Exercises = Exercises.get();
WorkoutData.$promise.then(function(response) {console.log('Resource 1 data loaded!')});
Exercises.$promise.then(function(response) {console.log('Resource 2 data loaded!')});
return $q.all([WorkoutData.$promise, Exercises.$promise]);
}
}
Working example can be found here.
Option 2:
As #ExplosionPills stated use object with resolve.
resolve: {
WorkoutData: ["WorkoutData", function (Gists) {
var WorkoutData = WorkoutData.get();
WorkoutData.$promise.then(function(response) {console.log('Resource 1 data loaded!')});
}],
Exercises: ["Exercises", function (Meta) {
var Exercises = Exercises.get();
Exercises.$promise.then(function(response) {console.log('Resource 2 data loaded!')});
}]
}
Working example can be found here.
Thanks #Explosion Pills for your inputs.
I have a single Ember app that needs to use different data depending on the domain that it's running on. For example, on domain1.com the site title might be "Domain 1 Website", whereas for domain2.org the site title could be "Cool Site!"
I need to be able to use the data in routes, controllers and templates.
My initializer so far:
import { request } from 'ic-ajax';
export function initialize(container, application) {
var domain = document.location.host;
return request('http://api/sites?domain=' + domain, {} ).then(function(response) {
// make the response available to routes, controllers and templates
});
}
export default {
name: 'site-data',
initialize: initialize
};
If you take a look at the docs:
http://guides.emberjs.com/v1.10.0/understanding-ember/dependency-injection-and-service-lookup/#toc_dependency-injection-with-code-register-inject-code
The second example
Ember.Application.initializer({
name: 'logger',
initialize: function(container, application) {
var logger = {
log: function(m) {
console.log(m);
}
};
application.register('logger:main', logger, { instantiate: false });
application.inject('route', 'logger', 'logger:main');
}
});
and the following explanation shows you how you can use .inject to make one of your variables, services or functions available to whatever objects you need within your application.