I have 2 request
html: <div>{{name}}</div>
json {"name": "Vasya"}
How with React parse this data and return <div>Vasya</div> ?
module.exports = React.createClass({
getInitialState: function () {
return {
previewData: {}, // {"name":"Vasya"}
previewHtml: {} // "<div>{{name}}</div>"
},
getTemplateDataStore: function (event, previewData) {
this.setState({
previewData: previewData
});
},
getTemplateHTMLStore: function (event, previewHtml) {
this.setState({
previewHtml: previewHtml
});
},
render: function () {
return // ?????????? need return <div>Vaysa</div>?
}
},
});
Related
I am receiving data in JSON from PHP and I want to detect if JSON have changed on Javascript side, not template side. Does anybody have solution? I am attaching a code.
export default {
name: 'dashboard_invoices',
data() {
return {
invoices: [],
newInvoices: [],
}
},
methods: {
loadDataInterval: function() {
this.$http.get('http://127.0.0.1/pdaserwis-crm/api/vue/vue?action=order_table').then(function (response) {
this.newInvoices = response.data;
if(this.newInvoices != this.invoices) {
// alert('Dodano nowa fakture');
this.invoices = this.newInvoices;
}
})
},
loadData: function() {
this.$http.get('http://website.pl').then(function (response) {
this.invoices = response.data;
})
}
},
created: function () {
this.loadData();
setInterval(function () {
this.loadDataInterval();
}.bind(this), 3000);
}
}
I want to catch if invoices have changed and view appropriate alert for that.
The problem solved. It took to compare both arrays with deep-equal by watch handler.
watch: {
invoices: {
handler(val, oldVal)
{
if(!(deepEqual(val, oldVal))) {
console.log('elo');
}
}
}
}
I'm trying to access my data property in my Vue.js component. Looks like I'm missing something obvious.
Here is a short version of my code. StoreFilter.vue is a wrapper for matfish2/vue-tables-2.
<template>
<store-filter :selected.sync="storeIds"></store-filter>
</template>
<script>
import StoreFilter from './Filters/StoreFilter';
export default {
components: {
StoreFilter
},
data() {
return {
options : {
requestFunction(data) {
console.log(this.storeIds); //undefined
return axios.get('/api/orders', {
params: data
}).catch(function (e) {
this.dispatch('error', e);
}.bind(this));
},
},
storeIds: [],
}
},
watch : {
storeIds(storeIds) {
this.refreshTable();
}
},
methods : {
refreshTable() {
this.$refs.table.refresh();
}
}
}
</script>
How to get storeIds from requestFunction?
Use a closure, see rewrite below.
data() {
let dataHolder = {};
dataHolder.storeIds = [];
dataHolder.options = {
requestFunction(data) {
// closure
console.log(dataHolder.storeIds); // not undefined
return axios.get('/api/orders', {
params: data
}).catch(function (e) {
this.dispatch('error', e);
}.bind(this));
}
}
return dataHolder;
}
I recommend using the created() way to handle this.
export default {
// whatever you got here
data () {
return {
options: {}
}
},
created () {
axios.get('/api/orders', { some: params }).then(response => this.options = response.data)
}
}
I use Angular 1.5 and I made a factory function which is return a literal object like this:
return {
item: null,
get: function() {
return item;
},
create: function() {
if (this.get()){
this.remove();
}
this.item = {};
},
remove: function() {
var item = this.get();
if (item) {
this.item = null;
}
},
add: function() {
if (!this.get()) {
this.create();
}
this.item.newprop = 'value';
}
}
please do not ask me to change to function declaration. I want a object with his own actions(functions) and properties that is working on.
This pattern (like get inside create so on..) I didn't copied from anywhere. so I'm wonder if has a name? It is best way to deal with function-black boxes?
What is the best way to put Promise inside? so every function should return a promise
every then function I need to use bind???
todo like this:
create: function () {
this.get()
.then(remove)
.then(function () {
this.item = {}; // BUT this === undefined!!
});
}
You have to use bind in every then callback function:
var myModule = {
item: null,
get: function() {
return Promise.resolve(this.item);
},
create: function() {
return this.remove().then(function() {
this.item = {};
}.bind(this));
},
remove: function() {
return this.get().then(function(item) {
if (item) {
this.item = null;
}
}.bind(this));
},
add: function() {
return this.get().then(function(item) {
return item || this.create();
}.bind(this)).then(function() {
this.item.newprop = 'value';
}.bind(this));
}
}
// Let see it working:
myModule.create().then(function() {
return myModule.get();
}).then(function(item) {
console.log("After create: ", item);
return myModule.remove();
}).then(function() {
return myModule.get();
}).then(function(item) {
console.log("After remove: ", item);
return myModule.add();
}).then(function() {
return myModule.get();
}).then(function(item) {
console.log("After add: ", item);
});
I have the following code:
var RiderComponent = React.createClass({
updater: function(){
this.props.metadata.update();
},
render: function () {
return (
<a href="#" onClick={this.updater}>
click!
</a>
);
}
});
var RiderList = React.createClass({
columnMeta: [
{
"columnName": "action",
"displayName": "",
"cssClassName": "buy",
"order": 6,
"customComponent": RiderComponent,
"update": this.update
}
],
update: function () {
this.props.update();
},
render: function () {
return <Griddle results={this.props.data}
useGriddleStyles={false}
showFilter={true}
columnMetadata={this.columnMeta}
columns={['action']}
resultsPerPage={18}
initialSort={'value'}
initialSortAscending={false}
noDataMessage={'Geen wielrenners gevonden.'}
/>
}
});
I want to run the update() function from RiderList in my RiderComponent when I click on an item. However I keep getting: 'Uncaught TypeError: this.props.metadata.update is not a function'.
What is the correct way to execute the update function in my RiderComponent?
RiderList is rendered in TeamManager:
var TeamManager = React.createClass({
getInitialState: function () {
return {
results: [],
activeRiders: [],
extraRiders: [],
availablePositions: []
}
},
componentWillMount: function () {
this.getExternalData();
},
getExternalData: function () {
var race_id = 1; // TODO: this is hardcoded
request = Api.getRidersPageUrl(race_id);
$.get(request, function (rsp) {
var data = rsp;
var activeRiders = []; // Riders with position 0..8
var extraRiders = []; // Riders with position 9..14
var availablePositions = Array.apply(null, {length: 9}).map(Number.call, Number); // Array 0..8;
if (data) {
// set data to arrays here
}
this.setState({
results: data,
activeRiders: activeRiders,
extraRiders: extraRiders,
availablePositions: availablePositions
});
}.bind(this));
},
render: function () {
return (
<RiderList update={this.getExternalData} data={this.state.results}/>
)
}
});
module.exports = TeamManager;
Here this.getExternalData just reloads the data in this.state.results.
EDIT: I got something working while using onRowClick={this.update} in RiderList render . However this fires when I click the row and not a specific button IN the row.
Updated answer based upon question new info,
var RiderComponent = React.createClass({
render: function () {
return (
<a onClick={this.props.metadata.update}>
click!
</a>
);
}
});
var RiderList = React.createClass({
getColumnMeta: function(){
return[
{
"columnName": "action",
"displayName": "",
"cssClassName": "buy",
"order": 6,
"customComponent": RiderComponent,
"update": this.update
}
]
},
update: function () {
this.props.update();
},
render: function () {
return <Griddle results={this.props.data}
useGriddleStyles={false}
showFilter={true}
columnMetadata={this.getColumnMeta()}
columns={['action']}
resultsPerPage={18}
initialSort={'value'}
initialSortAscending={false}
noDataMessage={'Geen wielrenners gevonden.'}
/>
}
});
I'm try to test my ReactJS mixin for drag and drop functionality using jasmine, karma and React TestUtils.
No exception is thrown but when debugging it seems that the function bound to the event listener not being executed when the event is simulated.
You can clone the it here:
https://github.com/itsh01/react-dragdrop/tree/testing-simutale-events
Thank you very much in advance.
Here is my test:
beforeEach(function () {
var CompDrag = React.createClass({
mixins: [DragDropMixin],
dragDrop: function dragDrop() {
return {
draggable: true,
dropType: 'test',
dataTransfer: {
test: true
}
};
},
render: function render() {
return React.createElement('div', {});
}
});
var CompDrop = React.createClass({
mixins: [DragDropMixin],
dragDrop: function dragDrop() {
var self = this;
return {
droppable: true,
acceptableTypes: ['test'],
drop: function (data) {
self.setState(data);
}
};
},
render: function render() {
return React.createElement('div', {});
}
});
elementDrag = React.createElement(CompDrag, {});
elementDrop = React.createElement(CompDrop, {});
});
...
it('should attach drop functionality when configured', function () {
var renderedDrag = TestUtils.renderIntoDocument(elementDrag);
var renderedDrop = TestUtils.renderIntoDocument(elementDrop);
var nodeDrag = renderedDrag.getDOMNode();
var nodeDrop = renderedDrop.getDOMNode();
var mockEvent = {
preventDefault: function () {},
dataTransfer: {
types: ["objtopass"],
setData: function () {},
getData: function () {
return JSON.parse({
dropType: 'test',
data: {
test: true
}
});
}
}
};
TestUtils.SimulateNative.dragStart(nodeDrag, mockEvent);
TestUtils.Simulate.dragOver(nodeDrop, mockEvent);
TestUtils.Simulate.drop(nodeDrop, mockEvent);
expect(renderedDrop.state).not.toBeNull();
});
Here is the mixin:
'use strict';
var _ = lodash;
var DragDropMixin = {
/*
* usage:
*
* mixins: [DragDropMixin],
* dragDrop: function () {
*
* return {
*
* // when dragging an item
* draggable: true,
* dropType: 'myItem',
* dataTransfer: { myItemData: property }
*
* // when dropping an item:
* droppable: true,
* acceptableDrops: ['myItem'],
* drop: function (myItem) {},
* };
* }
*
*/
isAttrEnabled: function (attr) {
return this.dragDropData && this.dragDropData[attr];
},
isDroppable: function () {
return this.isAttrEnabled('droppable');
},
isDraggable: function () {
return this.isAttrEnabled('draggable');
},
componentDidMount: function () {
var node = this.getDOMNode();
this.dragDropData = this.dragDrop();
if (this.isDroppable()) {
node.addEventListener('dragover', this.handleDragOver, this);
node.addEventListener('drop', this.handleDrop, this);
}
if (this.isDraggable()) {
node.draggable = true;
node.addEventListener('dragstart', this.handleDragStart, this);
}
},
componentWillUnmount: function () {
var node = this.getDOMNode();
if (this.isDroppable()) {
node.removeEventListener('dragover', this.handleDragOver);
node.removeEventListener('drop', this.handleDrop);
}
if (this.isDraggable()) {
node.removeEventListener('dragstart', this.handleDragStart);
}
},
handleDragOver: function (e) {
e.preventDefault();
},
handleDrop: function (e) {
var jsonData = e.dataTransfer.getData('objToPass'),
passedObj = JSON.parse(jsonData),
acceptableDrops = this.dragDropData.acceptableDrops;
e.preventDefault();
if (!this.dragDropData.drop) {
throw new Error('Must define drop function when using droppable');
}
if (_.includes(acceptableDrops, passedObj.dropType)) {
this.dragDropData.drop(passedObj.data);
}
},
handleDragStart: function (e) {
var objToPass = {
data: this.dragDropData.dataTransfer,
dropType: this.dragDropData.dropType
};
e.dataTransfer.setData('objToPass', JSON.stringify(objToPass));
}
};
Thanks again.
OK, got it.
I was actually listening to native events and simulating React synthetic events.
Fixed it by changing the mixin:
componentDidMount: function () {
var node = this.getDOMNode();
this.dragDropData = this.dragDrop();
if (this.isDroppable()) {
node.ondragover = this.handleDragOver;
node.ondrop = this.handleDrop;
}
if (this.isDraggable()) {
node.draggable = true;
node.ondragstart = this.handleDragStart;
}
},
And testing by triggering a native event
nodeDrag.ondragstart(mockEvent);
nodeDrop.ondragover(mockEvent);
nodeDrop.ondrop(mockEvent);
expect(DragDropMixin.handleDrop).toHaveBeenCalled();
expect(renderedDrop.state).toBeNull();