The question is simple and Im can't believe I cant found a solution (without context) for a situation as simple as this.
Im using react-intl.
I have an App.jsx with a child component Index.jsx with a SideBar.jsx with a CreateNewSomething.jsx.
In every components, the command
<FormattedMessage
id="new_object.fill_title"
defaultMessage='Please fill the "title" parameter'
/>
works perfectly thanks to <IntlProvider> provided by App.jsx
Unfortunally, I can't inject FormattedMessage as state value of a component.
Example:
<Input
s={6}
label={label_dash_title}
style={style_items_form}
onChange={this.onDashTitleChange}
onKeyPress={this.newDashHandleEnterKey}
error= { this.state.title_error }
/>
When the input field is not filled (is required) I want to print an error message.
Unfortunally I can't write:
const error_message = <FormattedMessage
id="new_dash.fill_title"
defaultMessage='Please fill the "title" parameter'
/>
this.setState({"title_error" : error_message});
because I get [object Object] and there is no property inside of it with my translated message.
Searching everywhere, I found I have to use this.props.intl.formatMessage({id: 'new_dash.fill_title'});
but this.props.intl is undefined.
I've tried, in App.jax, to include:
import {addLocaleData, IntlProvider, injectIntl, intlShape} from 'react-intl';
but it makes no difference.
I've tried to pass intl to every child component as props but intl is undefined in App.jsx too.
I don't know where is my mistake.
The module's Wiki explain the method but not how to use.
The solution is simple. You have to change the Export Syntax of your React Component and than this.props.intl will be magically available in the component:
export default injectIntl(MyComponent); //WORKS!!!
Unfortunally:
export default class injectIntl(MyComponent) extends React.Component //DOESN'T WORK
Related
I'm upgrading an Angular 2 app to version 4.0.1, and i'm having troubles with some tests.
I'm trying to get the attributes of a child component and test that the value given is correct.
Unfortunately, the attributes seems to be undefined in the test context, even when the component behave correctly in JiT build and AoT build.
The tests only broke after updating to Angular 4.0.1
Template of my parent component :
<div>
<div *ngIf="isComponentEnabled">
<child-component
superBaseUrl="super_url" i18n-superBaseUrl="frk|"
[slug]="slug"
[name]="name"
[age]="age">
</child-component>
.....
</div>
</div>
Test that breaks :
it(`GIVEN parent-component
THEN it should have correct attribute values`, () => {
componentInstance.name = 'Bar';
componentInstance.age = 90;
componentInstance.slug = 'foo';
attributes = specService.queryAttributes(
componentFixture, 'child-component');
console.log('HEYA -> ', specService.queryDebugElement(
componentFixture, 'child-component'));
expect(attributes['superbaseurl']).toBe('super_url');
expect(attributes['i18n-superbaseurl']).toBe('frk|');
expect(attributes['ng-reflect-slug']).toBe('foo');
expect(attributes['ng-reflect-name']).toBe('Bar');
expect(attributes['ng-reflect-age']).toBe('90');
});
Ouput of the breaking test :
Expected undefined to be 'foo'.
Expected undefined to be 'Bar'.
Expected undefined to be '90'.
Console log inside the test :
<child-component _ngcontent-c115="" i18n-superbaseurl="frk|" superbaseurl="super_url">
</child-component>
So i don't understand why in version 4 the attributes are not generated in this context. In version 2.X.X, we had the ng-reflect but it seems that this is no longer the case.
I've also tried to add a basic attribute (toto="toto") in the template, and this one shows up in the console.log of the test.
Does anybody have an idea why the attributes no longer shows up ?
P.S: The specService.queryAttributes is just a wrapper that call detectChanges before querying the attributes.
Found it !
For anyone interested, you have to add every sub components and compile them in version 4.0.1 in your TestBed if you want the attributes to be queryable.
In version 2.X, that was not required.
EDIT
Also, see, https://github.com/angular/angular/issues/15822 because i don't know if this is intended or not.
My code:
signup.emblem:
= validating-form onsubmit=(action 'signUp')
= input-field value=username
span {{usernameError}}
validating-form.js:
submit(event) {
console.log(this.get('username') //undefined
this.sendAction('onsubmit')
}
signup.js:
actions: {
signUp() {
console.log(this.get('username')) // value from input
}
}
As you can see the basic idea is some value in input gets validated in validating-form component and then if everything is fine it'll call some controller action or set some properties.
The problem is that apparently this form component isn't bind to properties from controller, even though its child component (input-field) is. Can you tell me what am I doing wrong here?
If I have to bind it explicitely, is there some way to do that with multiple properties at once?
The problem is that the standard input element isn't two-way bound to your username variable. You can bind it quickly using the action and mut helpers.
(example in handlebars, but you should be able to convert to emblem easily enough)
<input value={{username}} onblur={{action (mut username) value='target.value'}}>
This is saying:
on the onblur event
mut(ate) the username
to match the current target.value - which is the value of the input box
You can see evidence of this working in this twiddle
The other option is Input Helpers
I've not used these, as they don't follow the current Ember thinking of Data Down Actions Up, but it should be as simple as:
{{input value=username}}
And this will two-way-bind directly username.
My goal is to resolve to a generic component is the component doesn't exists. It managed to do it like this:
// app/components/dynamic-widget.js
...
widgetName: function() {
var name = this.get('config.name');
if (!this.container.resolve('component:'+name)) {
name = 'generic-widget';
}
return name;
}.property('config.name')
...
Then in app/templates/components/dynamic-widget.hbs:
{{component widgetName}}
Then, I could use my dynamic-component like this:
{{dynamic-widget 'foo-widget'}}
If foo-widget is not implemented, it fallback into generic-widget.
But since EmberJS 1.11, resolving a component from a component's container is deprecated:
DEPRECATION: resolve should be called on the registry instead of the container
So my question is, how can I check if a component actually exists without using this.container.resolve ?
Thanks a lot.
Does this.container.registery.resolve work?
Looking at the code in git https://github.com/emberjs/ember.js/blob/5fd2d035b30aa9ebfe73de824b3b283ec8e589cc/packages/container/lib/registry.js
Looks like you may also be able to use this.container.registery.has
I'm refactoring scaffolding templates and I hit a wall with this issue:
I was trying to call service (some security logic) from template _FORM.GSP - but in the code part, not in the output part
I've read and tried what was suggested in here: How do I call a Grails service from a gsp?
I've tried to use taglib, but my knowledge of grails may not be extensive enough for that
I've tried add import and def to the beginning of _FORM.GSP file (both grailsApplication and application instantiation of service were crashing on missing property application resp. missing property grailsApplication)
I've even tried to call the taglib from the code both directly as method isAllowedToEdit and also as g.isAllowedToEdit both crashing on unknown method resp. "no such property g"
it seems that template _form.gsp has different rules than standard gsp view
I want to do something like this:
private renderFieldForProperty(p, owningClass, prefix = "") {
boolean hasHibernate = pluginManager?.hasGrailsPlugin('hibernate')
boolean display = true
boolean required = false
if (hasHibernate) {
cp = owningClass.constrainedProperties[p.name]
display = (cp ? cp.display : true)
required = (cp ? !(cp.propertyType in [boolean, Boolean]) && !cp.nullable && (cp.propertyType != String || !cp.blank) : false)
}
/* trying to do this part */
// I want to assign value to cp.editable - so later I can render read-only fields in renderEdit
if (!mySecurityService.canEdit(springSecurityService.currentUser, owningClass.getClass(), actionName, p.name)) {
cp.editable = false
}
/* trying to do this part */
if (display) { %>
<div class="fieldcontain \${hasErrors(bean: ${propertyName}, field: '${prefix}${p.name}', 'error')} ${required ? 'required' : ''}">
<label for="${prefix}${p.name}">
<g:message code="${domainClass.propertyName}.${prefix}${p.name}.label" default="${p.naturalName}" />
<% if (required) { %><span class="required-indicator">*</span><% } %>
</label>
${renderEditor(p)}
</div>
<% } } %>
if there is any way to assign cp.editable - I'll try your suggestions
it seems that template _form.gsp has different rules than standard gsp view
The generated _form.gsp works same as other gsps but the template inside the scr/templates/scaffolding/ is different. Customizing the templates like you are doing is a bit more tricky. Keep in mind that the logic you are writing is for Grails on how to generate views(gsp). Meaning you are telling Grails to check some logic before generating the views in memory or in the file. You might be able to accomplish that to some extend for dynamic (in memory) scaffolding at run-time but for sure not for static scaffolding. That's because Grails
is not aware of currentUser when generating the templates.
Your problem will be much simpler if you generate your views and then customize them instead of modifying their templates. Then you can inject your services and do other checks. However, as you also mentioned those logics are better off in a tag library here.
Also since you mentioned security, rendering a field non-editable does not guaranty inability to edit your fields. I would suggest to put the check logic inside your controller for example in SAVE or UPDATE action to prevent any unauthorized user editing fields.
Did you try this?
<%# page import="com.myproject.MyService" %>
<%
def myService = grailsApplication.classLoader.loadClass('com.myproject.MyService').newInstance()
%>
this will work for sure.
go through this link : click here
I've generated testsuits via "cake bake testsuit" and used localhost/test.php for my app.
So, the is an error when I tried to run one of test (else tests are valid):
Fatal error: Class 'ErrorHandler' not found in Z:\home\prodvigator\www\cake\libs\object.php on line 201
This models and controllers are generated by scaffold and I don't think that an error is in this sources.
Using:
CakePHP 1.3
The latest SimpleTest
In my case, deleting all the files in the folder /app/tmp/cache/persistent solved the problem.
try checking the generated tests for an error that gets written at the top of the file.
sometimes i've been known to find something like this in both model and controller tests.
Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/New_York' for 'EDT/-4.0/DST' instead in /projectname/cake/console/templates/default/classes/test.ctp on line 22
In my case, the error was:
Fatal error: Uncaught Error: Class 'ErrorHandler' not found in C:\[path]\core\cake\libs\object.php on line 211
( ! ) Error: Class 'ErrorHandler' not found in C:\[path]\core\cake\libs\object.php on line 211
The error was happening to me when trying to visit http://localhost/user_accounts/index
I already had the view created at app\views\user_accounts\index.ctp with the following content:
<div>
Text from div
</div>
I had created the corresponding controller as well at app\controllers\user_accounts_controller.php:
<?php
class UserAccountsController extends AppController {
public function index() {
// Render the view in /views/user_accounts/index.ctp
$this->render();
}
}
?>
Since I was not associating a model to this controller, I was missing this: var $uses = array();. It would have saved me time if the error had been more explicit, something such as "You do not have a model associated to this controller".
The fix was:
<?php
class UserAccountsController extends AppController {
// Use this controller without a need for a corresponding Model file.
var $uses = array();
public function index() {
// Render the view in /views/user_accounts/index.ctp
$this->render();
}
}
?>