dynamic segments is not working - ember-cli

I have setup the following route in router.js:
this.route('reports',{path:'/reports/:report_name'}, function(){
});
I have following link setup in on of the hbs file:
{{#link-to 'reports' 'eod-2015'}}EOD 2015{{/link-to}}
in app/route/reports/index.js
model: function(params) {
console.log(params);
}
and I am getting {} as a result, how can I find report_name in my index.js route in app/route/reports folder?

Instead of trying to access param in app/route/reports/index.js you should access it in app/route/reports.js.
See demo.
Comparison:
Inside reports.js file: Object {report_name: "eod-2015"}
Inside index.js file: Object {}
If you would like to access reports params inside reports.index route you could do:
model(params) {
const parentParams = this.paramsFor('reports');
console.log('Accessing reports.js from index.js:', parentParams);
}

Related

What's the equivalent of Angular Service in VueJS?

I want to put all my functions that talk to the server and fetch data into a single reusable file in VueJS.
Plugins don't seem to be the best alternative. Template less components..?
In total there are 4 ways:
Stateless service: then you should use mixins
Stateful service: use Vuex
Export service and import from a vue code
any javascript global object
I am using axios as HTTP client for making api calls, I have created a gateways folder in my src folder and I have put files for each backend, creating axios instances, like following
myApi.js
import axios from 'axios'
export default axios.create({
baseURL: 'http://localhost:3000/api/v1',
timeout: 5000,
headers: {
'X-Auth-Token': 'f2b6637ddf355a476918940289c0be016a4fe99e3b69c83d',
'Content-Type': 'application/json'
}
})
Now in your component, You can have a function which will fetch data from the api like following:
methods: {
getProducts () {
myApi.get('products?id=' + prodId).then(response => this.product = response.data)
}
}
As I assume you want to re-use this method in multiple components, you can use mixins of vue.js:
Mixins are a flexible way to distribute reusable functionalities for Vue components. A mixin object can contain any component options. When a component uses a mixin, all options in the mixin will be “mixed” into the component’s own options.
So you can add a method in mixin and it will be available in all the components, where mixin will be mixed. See following example:
// define a mixin object
var myMixin = {
methods: {
getProducts () {
myApi.get('products?id=' + prodId).then(response => this.product = response.data)
}
}
}
// define a component that uses this mixin
var Component = Vue.extend({
mixins: [myMixin]
})
// alternate way to have a mixin while initialising
new Vue({
mixins: [myMixin],
created: function () {
console.log('other code')
}
})
I'm using Vue Resource mostly.
1.I create new file where I do connection to API endpoint using Vue.http.xxx.So let's say we have endpoint that output the posts.Create new directory in your project, I call it services, and then create file called PostsService.js - content looks like this:
import Vue from 'vue'
export default {
get() {
return Vue.http.get('/api/posts)
}
}
Then I go to component where I want use this service, and import it
import PostsService from '../services/PostsService'
export default {
data() {
return {
items: []
}
},
created() {
this.fetchPosts()
},
methods: {
fetchPosts() {
return PostsService.get()
.then(response => {
this.items = response.data
})
}
}
}
For more info about this approach, feel free to check my repo on GitHub https://github.com/bedakb/vuewp/tree/master/public/app/themes/vuewp/app
I suggest creating an API Provider that you can access from anywhere in your app.
Simply create a src/utils folder and inside of it a file called api.js.
In it, export your wrapper that knows how to communicate with your API as an object or a ES6 static class (I prefer how the latter looks and works if you're not afraid of classes). This provider can use any HTTP request library that you like and you can easily swap it later by changing a single file (this one) instead of hunting down the whole codebase. Here's an example of using axios, assuming we have a REST API available at api.example.com/v1 that uses SSL:
import axios from 'axios'
import { isProduction, env } from '#/utils/env'
const http = null // not possible to create a private property in JavaScript, so we move it outside of the class, so that it's only accessible within this module
class APIProvider {
constructor ({ url }) {
http = axios.create({
baseURL: url,
headers: { 'Content-Type': 'application/json' }
})
}
login (token) {
http.defaults.headers.common.Authorization = `Bearer ${token}`
}
logout () {
http.defaults.headers.common.Authorization = ''
}
// REST Methods
find ({ resource, query }) {
return http.get(resource, {
params: query
})
}
get ({ resource, id, query }) {
return http.get(`${resource}/${id}`, {
params: query
})
}
create ({ resource, data, query }) {
return http.post(resource, data, {
params: query
})
}
update ({ resource, id, data, query }) {
return http.patch(`${resource}/${id}`, data, {
params: query
})
}
destroy ({ resource, id }) {
return http.delete(`${resource}/${id}`)
}
}
export default new APIProvider({
url: env('API_URL') // We assume 'https://api.example.com/v1' is set as the env variable
})
Next, in your main.js file or wherever else you bootstrap the Vue app, do the following:
import api from '#/src/utils/api'
Vue.$api = api
Object.defineProperty(Vue.prototype, '$api', {
get () {
return api
}
})
Now you can access it anywhere in your Vue app as well as anywhere you import Vue itself:
<template>
<div class="my-component">My Component</div
</template>
<script>
export default {
name: 'MyComponent',
data () {
return {
data: []
}
},
async created () {
const response = await this.$api.find({ resource: 'tasks', query: { page: 2 } })
this.data = response.data
}
}
</script>
or:
// actions.js from Vuex
import Vue from 'vue'
export async function fetchTasks ({ commit }) {
const response = await Vue.$api.find({ resource: 'tasks', query: { page: 2 } })
commit('SAVE_TASKS', response.data)
return response
}
Hope this helps.
I think for your simple question the answer could be any ES6 module containing functions (equivalent to methods in class in ANgular) and directly importing them in components using ES6 imports and exports. There are no such services that could be injected in components.
You can make your own service where you can place all your HTTP server calls and then import that to the components where you want to use them.
Best is to make use of Vuex for complex state management applications because in Vuex you are able to handle all async calls via actions which always run asynchronously and then commit the mutation once you have the result.Mutation will directly interact with the state and will update it in an immutable manner (which is preferred). This is stateful approach.
There are other approaches as well. But these are the ones which I follow in my code.

How to create static parameters for use in data stores with rest proxy

I have an ExtJS 5.1.2 app that utilizes throughout the app a global config set of parameters defined in app_dir/app/Application.js, that looks like:
launch: function () {
Ext.Loader.setConfig({enabled: true});
// Static parameters
cardioCatalogQT.config = {
mode: 'test', // switch to control use of staging or production server
//protocol: 'https://',
protocol: 'http://',
//host: 'production_server',
//host: 'test_server,
host: '127.0.0.1:5000',
apiGetQ: '/get_query/',
//apiGetQ: '/api/get_query/',
apiWriteQ: '/remote_query_put',
apiReadQ: '/remote_query_get',
//apiMedsMenu: '/api/meds',
//apiMedsMenu: '/meds',
remove: 'none'
};
// TODO - Launch the application
Ext.onReady(function () {
});
}
This way, I only have one place to change the parameters that make up the url in Ajax calls, (in this case protocol, host and apiGetQ, for example give mr the ability to set url = cardioCatalogQT.config.protocol + cardioCatalogQT.config.host + cardioCatalogQT.config.apiGetQ), in one place to change the server address from development -> testing -> production, instead of having to find all references throughout the app.
However, due to the way that the ExtJs loads, I cannot use these config parameters in data stores that use rest proxies, since these stores seem to load before items in the Ext.Loader.
For example, I have the following store:
Ext.define('cardioCatalogQT.store.Diagnoses', {
extend: 'Ext.data.Store',
alias: 'store.Diagnoses',
config:{
model: 'cardioCatalogQT.model.Diagnosis',
storeId: 'Diagnoses',
autoLoad: true,
proxy: {
type: 'rest',
url: 'http://127.0.0.1:5000/menu/diagnoses',
//url: 'http://test_server/menu/diagnoses',
//url: 'https://prod_server/api/menu/diagnoses',
reader: {
type: 'json',
rootProperty: 'menu_test'
}
}
}
});
So, when I change from testing to development environments, for example, I have to explicitly change the n different references for url in my n stores that have rest proxies.
Is there a way to define a config object so that I can use it for these stores? I looked at some examples of a preloader, but this did not seem to have any use cases documented for a global config object, also I had tried implementing a loadmask in a preloader, but it really screwed with the behavior of my app.
I use to do like #Alexander propose, however I'll prefer the singleton way. More ExtJs/MVC like.
So just to complete, I share my version:
/**
* #class
*/
Ext.define("MyApp.config.Config", {
alternateClassName: [
'MyApp.config'
],
singleton: true,
constant: {
// ... whatever constant you need to put here
},
constructor: function() {
var constant = this.constant;
//
// here, if you need to process some stuff
// for example calculate some constant
// which depend of other constant
//
return constant;
}
});
Require in your app
// Be sure to require your class prior
// to your app classes
Ext.define('MyApp.Application', {
extend: 'Ext.app.Application',
requires: [
'Ext.app.*',
// ext stuff ...
'MyApp.config.Config',
// myApp stuff ...
]
// ...
});
Example usage:
Ext.define('MyApp.store.MyStore', {
// ...
proxy: {
type: 'rest',
url: MyApp.config.remoteUrl
}
})
We had similar issues, so we have put our global ConnectionSettings object into a script tag that is in index.html, before Ext.
<script type="text/javascript">
ConnectionSettings = {
...
...
};
</script>
<!-- The line below must be kept intact for Sencha Cmd to build your application -->
<script id="microloader" ...
That way, the object is available wherever we need it in our Ext code.

reference sails config outside module.exports

How can I use sails.config outside the module.exports? I'm trying to pass sails.config variables to another object, something like below;
var foo = new Foo(sails.config.myconf.myVar);
module.exports {
bar : function(){
// Use foo here
foo.blah();
}
};
(Same question also asked in a comment in this Create config variables in sails.js? See #jreptak comment)
Each files of Sails config is a module then if you want to use it, you just have to import it.
Here is an example to import Sails connections of sails.config.connections module.
Be careful about the path of the module in the require, it must be relative.
var connections = require('../../config/connections');
This was not possible in Sails v0.9. However, this is now possible in Sails v0.10 onwards.
Here's the specific issue on github: https://github.com/balderdashy/sails/issues/1672
So now you can do something like this:
//MyService.js
var client = new Client(sails.config.client);
module.exports = {
myMethod: function(callback){
client.doSomething();
}
}
If you're stuck with Sails v0.9, I would recommend that you follow the workaround specified in the github issue:
//MyService.js
var client;
module.exports = function(){
client = client || new Client(sails.config.client);
return {
myMethod: function(){
client.doSomething();
}
}
}
Which can be used like so:
//SomeController.js
module.exports = {
list: function(req,res){
MyService().myMethod();
}
}
You can't do this, if you want to access sails.config params you have to create a custom hook http://sailsjs.org/documentation/concepts/extending-sails/hooks and do your 'magic' in it

Is there a way to create and run a dynamic script from karma.conf.js

I'm using karma to run tests on an angularjs application.
There are a couple JavaScript functions that I would like to run at start-up, but they need to be dynamically created based on some system data. When running the app, this is handled with node.
Is there any way to create a script as a var and pass it to the files: [] rather than just using a pattern to load an existing file?
I can make this work by creating the file, saving it to disk then loading it normally, but that's messy.
You can create your own karma preprocessor script.
For a starting point use the following as example:
var fs = require('fs'),
path = require('path');
var createCustomPreprocessor = function (config, helper, logger) {
var log = logger.create('custom'),
// get here the configuration set in the karma.conf.js file
customConfig = config.customConfig || {};
// read more config here in case needed
...
// a preprocessor has to return a function that when completed will call
// the done callback with the preprocessed content
return function (content, file, done) {
log.debug('custom: processing "%s"\n', file.originalPath);
// your crazy code here
fs.writeFile(path.join(outputDirectory, name), ... , function (err) {
if (err) {
log.error(err);
}
done(content);
});
}
};
createCustomPreprocessor.$inject = ['config', 'helper', 'logger'];
module.exports = {
'preprocessor:custom': ['factory', createCustomPreprocessor]
};
Add a package.json with the dependencies and serve it as a module. ;)
For more examples have a look to more modules here: https://www.npmjs.org/search?q=karma%20preprocessor

Using port.emit and port.on in a firefox extension

Can someone please explain the context in which port.on and port.emit are used in a firefox extension?
From the official documentation I imagine that this should work:
//main.js
var someData = "Message received";
self.port.emit("myMessage", someData);
self.port.on("myMessage", alert(someData));
but I get
Error: self is not defined.
After attaching this to a defined object like this:
var self = require("sdk/self");
self.port.emit("myMessage", someData);
I get
Error: port is not defined.
If you use the page-mod module to inject a content script into a web page, you then use self.port in the content script to communicate back with main.js. For example:
main.js:
var data = require('sdk/self').data;
require('sdk/page-mod').PageMod({
include: ["*"],
contentScriptFile: [data.url('cs.js')],
attachTo: ["existing", "top"],
onAttach: function(worker) {
worker.port.emit('attached', true);
}
});
cs.js:
self.port.on('attached', function() {
console.log('attached...');
});
For the related documentation, start here:
https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Content_Scripts