Dependency injection for Angular in Rails - ruby-on-rails

The syntax for dependency injection in Angular.js is confusing me.
I have a Rails app that is using Angular. One of the directives needs to use the $cookies service. So I have the main Javascript file where I declare the angular app, and a directives folder with js-files for my directives.
So this is the relevant part of the main js file. I'm trying to inject the ngCookies module into it:
app.js
angular.module('myApp', [
'templates',
'ngCookies'
]);
and here is the file with the directive that needs the $cookies service:
my-directive.js
angular.module('myApp')
.directive("myDirective", ['$cookies', function(){
return {
restrict: 'E'
templateUrl: "my-directive-template.html",
scope: {
article: '=ngModel'
},
link: function(scope, element, attrs){
scope.myFunction = function(){
$cookies.example = "hello world"; // set a cookie
};
}
};
}]);
So I'm trying to inject the ngCookies module into the myApp module and then inject the $cookies service into the directive.
This syntax doesn't work; Firebug gives me an error: "Error: $cookies is undefined".
Could you please help me figure out how to inject dependencies in Angular properly?

Oh my! I guess the only thing I needed was to add the $cookies as an attribute for the function declaration as well so that the line
.directive("myDirective", ['$cookies', function(){
became
.directive("myDirective", ['$cookies', function($cookies){

Related

Asp.net 4.8 MVC + Vite + Svelte + HMR?

I have a legacy application built in ASP.NET 4.8 MVC.
I would like to start building some client side features in Svelte - having svelte components rendering inside razor views. This I have working. I can render a svelte component anywhere in the razor page.
However vite has some problem (im guessing with HMR?), and it keeps refreshing the razor page (https://localhost:44300/somefeature) every few seconds.
Environment
asp.net 4.8 mvc loads to https://localhost:44300/
vite is loading on http://localhost:3000/
Here is what i have so far. I ran npm init vite#latest -> selected svelte + svelte TS
vite.config.js
import { defineConfig } from 'vite'
import { svelte } from '#sveltejs/vite-plugin-svelte'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
svelte({
compilerOptions: {
customElement: true,
}
})
],
build:{
// generate manifest.json in outDir
manifest: true,
rollupOptions: {
// overwrite default .html entry
input: '/src/main.ts'
}
}
})
Then i followed the instructions here https://vitejs.dev/guide/backend-integration.html and added this to the razor page:
#Html.Raw("<script type='module' src='http://localhost:3000/#vite/client'></script>")
<script type="module" src="http://localhost:3000/src/main.ts"></script>
(Note - had to use Html.Raw because it wouldnt let me escape the # correctly - even with ##)
At this point it is rendering my Svelte component perfectly.
The issue however is that vite is now reloading my page every 2 seconds or so - im guessing because HMR is no longer working correctly as the console just says: [vite] connecting...
Can anyone point me in a direction either to get HMR working whilst using another Backend server? For some reason it works in asp.net core, but not so in ASP.NET 4.8. Any observations to help?
Thanks in advance!
Ok i got it working. Here is my vite.config.js. Pay special attention to the
input, outDir and server nodes, and adjust them to your scenario. The proxy is important, you can either set it to your https or http mvc endpoint and port that asp.net spins up for you.
Here is the config:
export default defineConfig({
plugins: [
svelte()
],
build:{
// generate manifest.json in outDir
manifest: true,
rollupOptions: {
// overwrite default .html entry
input: 'Scripts/svelte/app.js',
},
outDir: 'Scripts/svelte/dist'
},
server: {
proxy:{
'*' : {
target: 'http://localhost:26688',
changeOrigin: true
}
},
hmr: {
protocol: 'ws'
}
}
})
Its pretty cool - you get instant HMR of any svelte component inside a razor page without losing any razor state.
THANK YOU!!!! This is exactly what I was looking for to include my react code in my old Asp.Net 4.8 site with hot module reload!
For other's the thing I had to include in my cshtml to make the react stuff load properly was:
<script type="module">
import RefreshRuntime from "http://localhost:9999/##react-refresh"
RefreshRuntime.injectIntoGlobalHook(window)
window.$RefreshReg$ = () => {}
window.$RefreshSig$ = () => (type) => type
window.__vite_plugin_react_preamble_installed__ = true
</script>
If you don't include this you get an error saying '#vitejs/plugin-react can't detect preamble'.
I am hosting the development site in IIS locally so to serve up the local files, I just created a /src folder off of the root or my application pointing to the src in my react directory and it worked beautifullly!!

Swagger UI: specify responseInterceptor in swagger-config.yaml

I am trying to use swagger-config.yaml to configure swagger UI as mentioned in the document.
The document mentions parameters like requestInterceptor or responseInterceptor, but they are all defined as a function. I don't think I can really put a function in yaml file per specification, and I have tried to put function in it as string but swagger ui won't pick it up.
My question is can I use requestInterceptor or responseInterceptor in the swagger-config.yaml file or these parameters cannot be used in config file? Thanks.
You are right that the requestInerceptor and responseInterceptor cannot be defined in the swagger-config.yaml file. They can only be defined in JavaScript:
const ui = SwaggerUIBundle({
"dom_id": "#swagger-ui",
deepLinking: true,
...
requestInterceptor: function(req) {
req.headers["MyCustomHeader"] = "value";
return req;
}
})

Dart Project with RequireJS

I am trying to include web3.js into my Dart project. I am trying to do this via requirejs
I've created a requirejs config, which appears to load a valid web3 instance except, now my dart code never initializes! It appears that the requirejs main.js prevents my main.dart from executing. Could really use advice on how to get everything playing nicely.
main.js
requirejs.config({
appDir: ".",
baseUrl: "scripts",
paths: {'web3': 'https://cdn.jsdelivr.net/gh/ethereum/web3.js/dist/web3.min'}
});
require(['web3'], function(web3) {
console.log("Loaded :)");
if (typeof web3 !== 'undefined') {
web3 = new Web3(web3.currentProvider);
} else {
// set the provider you want from Web3.providers
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}
console.log(web3);
return web3;
});
The function does get called and is passed an initialized web3 object.. except strong text

requirejs 2.1.11 + jquery mobile 1.4.2 throw error

It seems that requireJS does not work properly with jquery mobile 1.4.2
in the app.js I have the minimum configuration for RequireJS 2.1.11
requirejs.config({
'baseUrl': 'js',
'paths': {
'jquery': 'lib/jquery-1.10.2',
'jquerymobile': 'lib/jquery_mobile/jquery.mobile-1.4.2'
}
});
And then when I am trying to use jquerymobile dependancy I have:
define(['require', 'jquery', 'jquerymobile' ], function (require, $) {
console.log(success)
})
This shows an error in the Chrome console
Failed to load resource: the server responded with a status of 404 (Not Found) http://localhost:63342/app/www/js/demos/js/jquery.js
Uncaught Error: Script error for: demos/js/jquery
http://requirejs.org/docs/errors.html#scripterror require.js:141
This is caused by jquery mobile code:
(function ( root, doc, factory ) {
if ( typeof define === "function" && define.amd ) {
// AMD. Register as an anonymous module.
define( [ "demos/js/jquery" ], function ( $ ) {
factory( $, root, doc );
return $.mobile;
});
} else {
// Browser globals
factory( root.jQuery, root, doc );
}
}
When I change with jquery mobile 1.3.2 it seems that require JS is working correctly. Is there a way to use requireJS with Jquery mobile 1.4.2 ?
You're not using the correct source. When I go straight to the official source, I see:
(function ( root, doc, factory ) {
if ( typeof define === "function" && define.amd ) {
// AMD. Register as an anonymous module.
define( [ "jquery" ], function ( $ ) {
factory( $, root, doc );
return $.mobile;
});
} else {
This is exactly what I would expect: jQuery Mobile depends on jquery, which is the way you always should require jQuery with RequireJS.
The demos/js/jquery dependency that you see in the code you show in your question does not make much sense. It would be possible to make it work but it would require everybody who uses jQuery Mobile to go through an unnecessary configuration hoop. This is a big red flag that something is wrong.

Rails 3 + angularjs + minification does not work in production: Unknown provider: eProvider

I've followed all the instructions I can find for fixing minification, e.g.
var MyController = function(renamed$scope, renamedGreeter) {
...
}
MyController.$inject = ['$scope', 'greeter'];
and
someModule.factory('greeter', ['$window', function(renamed$window) {
...;
}]);
yet angular refuses to work still. It always throws the error "Unknown provider: eProvider"
Here are my two attempts to get it working... can anyone help?
https://github.com/jemminger/angular-test1
https://github.com/jemminger/angular-test2
They've already had the assets precompiled and development mode is configured to work as production, so you should just be able to "rails s" to see it (not) work.
Found it! They never said to apply the injection fixes to services too... The solution is to change this:
angular.module('itemServices', ['ngResource']).
factory('Item', function($resource){
return $resource('items/:item_id.json', {}, {
query: {method:'GET', params:{ item_id: 'all' }, isArray:true}
});
});
to this:
angular.module('itemServices', ['ngResource']).
factory('Item', ['$resource', function($resource){
return $resource('items/:item_id.json', {}, {
query: {method:'GET', params:{ item_id: 'all' }, isArray:true}
});
}]);
Remember, to also use DI on controllers within directives. Took me hours... CS example:
wrong:
controller: ($scope) ->
$scope.closeModal = ->
ModalService.close()
right:
controller: ["$scope"
($scope) ->
$scope.closeModal = ->
ModalService.close()
]
Make sure to apply the DI pattern to ALL function definitions that require injection within your module. It can be easy to miss one. If you're using a routeProvider, factory, services, etc., they all need to have the DI pattern applied. I ended up deploying multiple times before I caught them all :P

Resources