Getting javascript var from database record in Smarty - javascript

I'm working on a PrestaShop page with the file extension ".tpl". I get the javascript code to auto complete like this:
var currencies = [
{ value: 'Afghan afghani', data: 'AFN' },
{ value: 'Albanian lek', data: 'ALL' },
{ value: 'Algerian dinar', data: 'DZD' },
{ value: 'European euro', data: 'EUR' },
{ value: 'Angolan kwanza', data: 'AOA' },
{ value: 'East Caribbean dollar', data: 'XCD' },
{ value: 'Vietnamese dong', data: 'VND' },
{ value: 'Yemeni rial', data: 'YER' },
{ value: 'Zambian kwacha', data: 'ZMK' },
{ value: 'Zimbabwean dollar', data: 'ZWD' },];
While I also already have a foreach like the example below:
{foreach from=$currencies item=currency}
{$currency.name}
{$currency.code}
{/foreach}
How to output currencies value with foreach? I tried this code:
var currencies = [
{foreach from=$currencies item=currency}
{ value: '{$currency.name}', data: '{$currency.code}' },
{/foreach},];
http://i.stack.imgur.com/DhYgL.jpg

You can use json_encode to output a PHP array to JavaScript
This is the JavaScript code in the TPL
var currencies = JSON.parse('{$currencies|json_encode}');
{$currencies|json_encode} will output something like this
[{ value: 'Afghan afghani', data: 'AFN' },
{ value: 'Albanian lek', data: 'ALL' },
{ value: 'Algerian dinar', data: 'DZD' }, ...]
This output will be passed to the JavaScript function JSON.parse which will transform the output string to a JavaScript object

var newArray = [];
for (var i=0; i < currencies.length; i++) {
newArray.push({value: whatever, data: whateverVar})
}
I am still not sure what you want but that is the best I can give from what I think you want.

Related

Object gets duplicated inside array

This is the result I want to achieve
dataset: [
dataset: [
{
seriesname: "",
data: [
{
value: "123",
},
{
value: "123",
},
]
},
]
]
My problem right now is that the second dataset gets duplicated.
This is how I am setting it (val is an integer and allYears is an array of integers):
this.grphColumn.dataSource.dataset[0].dataset = this.allYears.map(el => {
return {
seriesname: "Planned",
data: [{value: val}, {value: val}]
}
});
How can I make it so the dataset doesn't get duplicated?
You have to map the values separately, if you dont want the seriesName to be Repeated..
const yearsMap = this.allYears.map((el) => { return { value: el } });
this.grphColumn.dataSource.dataset[0].dataset = {
seriesname: "Planned",
data: yearsMap
}

React - Loop through multiple nested arrays json object response then update State

I have some data that has the following shape. The schedule data also has other identifying information attached to it, being schedules.included which is an array of arrays. I want to loop through each included array and find it by type element. I'm not entirely sure how to get each included[] by type then update state with data from each array, respectively. Is forEach the correct approach?
const schedules = {
data: [
{
id: "2147483610",
type: "Schedule"
}
],
included: [
{
id: "21468486",
type: "Query",
name: "Query1"
},
{
id: "43573457345",
type: "DataSource",
name: "DataSource1"
}
]
};
I then want to update state with whatever data I need.
getData = () => {
axios({
method: "get",
url: `/endpoint/with/this/data`
})
.then(response => {
console.log(response);
var obj = schedules.included[i].type;
obj.forEach(function(type) {
alert(type.name);
});
this.setState({
schedules: schedules.data,
//update with name from type Query
});
})
.catch(error => console.log(error.response));
};
If you want to find the name of the element from the included array which has type = Query, and there is only one such element:
var query = schedules.included.find(el => el.type == "Query");
console.log(query.name); // output Query1
If there is more than one query element you could use filter to get all query elements, then loop thru them doing stuff with each one.
var queries = schedules.included.filter(el => el.type == "Query");
queries.forEach(q => console.log(q.name));
If there is only one element with the type you are looking for then you can use find or if there is more use filter.
const schedules = {
data: [
{
id: "2147483610",
type: "Schedule"
}
],
included: [
{
id: "21468486",
type: "Query",
name: "Query1"
},
{
id: "43573457345",
type: "DataSource",
name: "DataSource1"
}
]
};
const typeMatched = schedules.included.find( included => included.type === "Query");
console.log(': ', typeMatched);
const schedulesObj = {
data: [
{
id: "2147483610",
type: "Schedule"
}
],
included: [
{
id: "21468486",
type: "Query",
name: "Query1"
},
{
id: "43573457345",
type: "DataSource",
name: "DataSource1"
},
{
id: "21468482",
type: "Query",
name: "Query2"
},
{
id: "21468484",
type: "Query",
name: "Query3"
},
]
};
const typeMatchedArray = schedulesObj.included.filter( included => included.type === "Query");
console.log('Query Type List: ', typeMatchedArray)

If in object pushing

I want to create object that will contain x-amount datasets only if the data for each of the datasets.data (londonTemp, nyTemp) is higher than 0. My attempt would be to put if in front of the second dataset object, but cannot do it.
var container = {
temp : {
labels: "",
datasets: [
{
label: "London",
type: "bar",
data: londonTemp
},
{ // this object
label: "NY", // to exist
type: "line", // only if
data: nyTemp // nyTemp > 0
}
]
}
};
Push this object in separate if block:
var container = {
temp: {
labels: "",
datasets: [{
label: "London",
type: "bar",
data: londonTemp
}]
}
};
if (nyTemp > 0) {
container.temp.datasets.push({
label: "NY",
type: "line",
data: nyTemp
})
}
I would filter by data > 0
var container = {
temp : {
labels: "",
datasets: [
{
label: "London",
type: "bar",
data: 5
},
{ // this object
label: "NY", // to exist
type: "line", // only if
data: 0 // nyTemp > 0
}
]
}
};
container.temp.datasets = container.temp.datasets.filter(function(one){return one.data > 0});
Another way is to filter all items whose data is greater than 0.
container.temp.dataset.filter(item => item.data > 0);
I personally think that using filter is cleaner and more robust than using if + push.

Convert flat json structure to hierarchical

I cannot get my head around this problem.
I have a settings object which looks like
const setting = [
{
Key: 'root/',
Value: null,
},
{
Key: 'root/second-root/',
Value: null,
},
{
Key: 'root/second-root/names/',
Value: null,
},
{
Key: 'root/second-root/names/capital-letter',
Value: true,
},
{
Key: 'root/second-root/countries/',
Value: null,
},
{
Key: 'root/second-root/countries/enabledcountries',
Value: 'US,UK,DK',
},
{
Key: 'root/second-root/countries/async',
Value: 'true',
},
{
Key: 'root/second-root/countries/manual',
Value: 'true',
},
{
Key: 'root/second-root/countries/limit',
Value: '4200',
},
{
Key: 'root/second-root/names/onyl-last-name',
Value: false,
},
];
I need to convert it to look like
const wantedResult = [
{
'root': {
'Value': null,
'second-root': {
'Value': null,
'names': {
'Value': null,
'capital-letter': {
'Value': true,
}
'onyl-last-name': {
'Value': false,
}
},
'countries': {
'Value': null,
'enabledcountries': {
Value: 'US,UK,DK',
},
'async': {
Value: 'true',
},
'manual': {
Value: 'true',
},
'limit': {
Value: '4200',
}
}
}
}
}
];
The it is the Key property which controls the hierarchy. If it ends with a / the item is a directory else it is a value.
Problem is that the flat structure doesnt have to return the items in a correct order. Like in the example, the last item is 'root/second-root/names/onyl-last-name', even though the names hiarchy was in the beginning of the flat structure.
I have tried a form of array.reduce but get stuck every time. Could someone please help me.
You could iterate the array and take the value without the last slash and split it as path to the object for assigning the value.
If necessary put the result in an array.
In forEach works
a destructuring assignment for getting the key and value out of the object,
a replacement which looks for a slash at the end of the string with an empty string,
a splitting of the string by slash, it returns an array with strings without slashes,
using Array#reduce with the result object as accumulator.
Inside it uses a default pattern with a logical OR || which check if the left side is a truthy value and if not, it assigns an object. This value is returned for the check with the next key.
at the end of the iteration it retuns an object reference and then the value gets assigned.
var setting = [{ Key: 'root/', Value: null }, { Key: 'root/second-root/', Value: null }, { Key: 'root/second-root/names/', Value: null }, { Key: 'root/second-root/names/capital-letter', Value: true }, { Key: 'root/second-root/countries/', Value: null }, { Key: 'root/second-root/countries/enabledcountries', Value: 'US,UK,DK' }, { Key: 'root/second-root/countries/async', Value: 'true' }, { Key: 'root/second-root/countries/manual', Value: 'true' }, { Key: 'root/second-root/countries/limit', Value: '4200' }, { Key: 'root/second-root/names/onyl-last-name', Value: false }],
result = {};
setting.forEach(({ Key, Value }) => Key
.replace(/\/$/, '')
.split('/')
.reduce((o, k) => o[k] = o[k] || {}, result).Value = Value
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Add object array to jquery-ui autocomplete

I'm using jquery-ui plugin, what I'm trying to accomplish is to use an array of pair values (Key and label value) as the source for an autocomplete text input.
My array looks like:
var valuesArray = [{
label: 'Name_1',
key: 1
}, {
label: 'Name_2',
key: 2
}, {
label: 'Name_3',
key: 3
}, {
label: 'Name_4',
key: 4
}];
I need the label attribute to appear in the text input while getting the key attribute when retrieving the input text element value.
Thanks in advance
I think that from what i understand, this is what you need.
$("#someID").autocomplete({
source: function(request, response) {
var data = [{
label: 'Name_1',
key: 1
}, {
label: 'Name_2',
key: 2
}, {
label: 'Name_3',
key: 3
}, {
label: 'Name_4',
key: 4
}];
response(data);
},
select: function( event, ui ) {
$( "#someID" ).val( ui.item.key);
alert(ui.item.key);
return false;
}
});

Categories

Resources