Ext JS 4.2 metadata tpl not recognized - json

First time, long time...
I am using Ext JS 4.2.2.1144
I have a grid and my query from the server(php) is returning metadata in the form of json that was previously generated when a user decides to realign and resize the columns and then save that information. All of the fields like width, dataIndex, align, and all that are reconfiguring the grid just fine when using the metaChanged function. The problem that I am having is that one of the columns needs to send over the information for a tpl which is actually the location of an image to show. My Json looks like this
{
"totalCount":"2",
"root":"items",
"metaData":
{
"fields":[
{"name":"queryid"},
{"name":"createUser"},
{"name":"subject"},
{"name":"priorityImage"}
],
"columns":[
{
"dataIndex":"queryid",
"width":100,
"text":"Queryid"
},
{
"dataIndex":"createUser",
"width":100,
"text":"Owner",
"align":"center"
},
{
"dataIndex":"subject",
"width":200,
"text":"Subject",
"hidden":true
},
{
"dataIndex":"priorityImage",
"width":70,"text":"Priority",
"hidden":true,
"align":"center",
"xtype":"templatecolumn",
"tpl":['<img src="_images/{priorityImage}" height="20px" width="20px" />']
}
]
},
"items":[
{
"queryid":"1",
"createUser":"1",
"subject":"Here is a new project",
"priorityImage":"orange.png"
},
{
"queryid":"1",
"createUser":"1",
"subject":"SAL Form 4",
"priorityImage":"roundlightPurple.png"
}
]
}
I have tried all kinds of different ways of sending the tpl for this last column but none of them are success. Anybody with any clues on how to accomplish this? The result ends up being the text and not the actually image. If I load the grid directly from the store using the default model, I get the image from the tpl but just not when doing it through metadata. I have tried single quotes, double quotes, no braces, with braces, lol. Im out of ideas to try. Hopefully I am being clear enough. Anyhoo, thanks for any help in advance, this one is really driving my crazy,
thanks,
C5

I have done something similar long time ago when I needed to send renderers (functions) but they always appear as text. At that time I haven't found other way but to scan the received metaData to see if there is a renderer and call eval on the received text to get the function.
Although not a "do this" answer, I hope it helps.

I figured a work around for this although maybe not the most ideal solution it does work.
When sending the tpl to the Server, it actually gets translated from
<img src="_images/{priorityImage}" height="20px" width="20px" /> to
<img src="_images/{priorityImage}" height="20" width="20" />
So here is my fix for now anyway:
Before I call the code to load the store
Ext.getCmp('lblCurrentMetaGrid').setText('projectsGridGrid');
store.on('metachange', metaChanged, this);
Then in the metaChanged function it looks like this:
function metaChanged(store,meta){
var gridname = Ext.getCmp('lblCurrentMetaGrid').text;
var grid = Ext.getCmp(gridname);
for(var c = 0; c < meta.columns.length; c++ ){
var column = meta.columns[c];
var tpl = column.tpl;
if ( tpl !== undefined){
meta.columns[c].tpl[0] = meta.columns[c].tpl[0].replace('<','<');
meta.columns[c].tpl[0] = meta.columns[c].tpl[0].replace('>','>');
meta.columns[c].tpl[0] = meta.columns[c].tpl[0].replace(/\"/g,'"');
}
}
//lets look at all the metadata
grid.reconfigure(store,meta.columns);
}
Now, I am getting my image in the grid.

Related

Looping through JSON array from an API, can get all results or none result, no luck with loops, using jQuery

I'm just trying something new out to get skills more up to date, and am a bit stumped on this jQuery API response. I have all of the results going to console fine, I have them displaying on an html file, but all together as one. I want to put a break between each word (it's [Words API][1] and I'm stuck. I usually use PHP, but well, it's not practical for what I'm planning. Here is the code, and I'll show the best I can in results. Thank you!
<div id="div1">
// This is where it shows up as "unmitigated,butcherly,crimson,gory,homicidal,internecine"
</div>
<script>
const settings = {
"async": true,
"crossDomain": true,
"url": "https://wordsapiv1.p.rapidapi.com/words/bloody/similarTo",
"method": "GET",
"headers": {
"x-rapidapi-key": "<my key>",
"x-rapidapi-host": "<host>"
}
};
$.ajax(settings).done(function (response) {
console.log(response);
$("#div1").html(response.similarTo + " "); // This puts a comma between each word, but no spacing, when I want a line break. I need to be able to customize results, make them links, add styles, etc.
});
Thank you so much! Only 3 more weeks of strict "stay at home" Covid19 orders. I'm learning a lot!
I guess you have a text string in response.similarTo containing a mess of comma-separated words.
You can process them like this. Split breaks them at commas. The rest of this code formats them into an HTML list and displays them.
const results = []
const words = response.similarTo.split(',')
for (const word of words) {
/* do what you will with each word in turn, for example... */
results.push('<li>' + word + '</li>')
}
$("#div1").html('<ol>' + results.join('') + '</ol>')

ReactJS fetch JSON API Data -- The correct way?

I have been fighting with ES6 trying to come up with, what should be, a pretty straightforward operation. I want to call JSON API data for Bitcoin from one of the three following websites:
https://cryptowat.ch
https://coinmarketcap.com/
https://www.cryptocompare.com/
All three sites API endpoints go straight to the price I want and I think this may be the problem. There is no array of data, just the specific price. In my example using #3 above, the only object is "USD". That being said, I think I'm overthinking the process as getting into APIs with much more data and arrays of data -- I have accomplished using ReactJS.
Trying to reach a single endpoint that shows up as the "State" in the React DOM Inspector as "USD" and is pulling in the correct price, I cannot get the price to render on the page even though ReactJS is seeing it and capturing it.
My code:
var BitcoinApp = React.createClass({
getInitialState: function() {
return {
"USD": []
}
},
componentDidMount: function() {
var th = this;
this.serverRequest =
axios.get(this.props.source)
.then(function(result) {
th.setState({
USD: result.data.USD
});
})
},
componentWillUnmount: function() {
this.serverRequest.abort();
},
render: function() {
return (
<span>
{this.state.USD.map(function(Data) {
return (
<div key={Data.USD} className="testbtc">
<p>{Data.USD}</p>
</div>
);
})}
</span>
)
}
});
ReactDOM.render(<BitcoinApp source="https://min-api.cryptocompare.com/data/price?fsym=BTC&tsyms=USD&e=Coinbase" />, document.querySelector("#btcPrice"));
I will mention that I have done a lot of research into this and have found a lot of answers -- all different! Everyone knows the ReactJS docs are severely outdated so finding the right path with ReactJS is difficult to say the least. Also, I'm using "axios" to "GET" the API data as I've read that "fetch" isn't globally supported yet? Is this still the case in 2017?
Using the above method, I can see this in the Inspector:
But when I go over to the "Console" portion of the inspector, I'm told that "this.state.USD.map is not a function".
I feel like I'm right on the cusp of solving this task, but I think I'm getting something wrong with the mapping of the promise.
the problem is that:
th.setState({
USD: result.data.USD
});
is seting not iterable object. I mean that this.state.USD.map is not a function means that USD is not an array (and you can see this in console).
Try this to see what happens:
th.setState({
USD: [result.data.USD]
});
However tho, you wrote:
There is no array of data, just the specific price.
then I think the best solution is to change just the render method and initial state:
render: function() {
return (
<span>
<div className="testbtc">
<p>{this.state.USD}</p>
</div>
</span>
)
}
getInitialState: function() {
return {
"USD": "",
}
},

How do I format my AngularJS data model?

Hi I am just beginning with angular and I am struggling to find the answer to what I'm sure is quite a simple thing to do.
I am currently getting the values of some input boxes and pushing them into my scope. This is creating one long 'array' eg:
['data-1','data-2','data-3']
I would like to format my data in the following way instead
$scope.data = [
{
'header1': 'data1-1',
'header1': 'data1-2',
'header1': 'data1-3'
},
{
'header1': 'data2-1',
'header1': 'data2-2',
'header1': 'data2-3'
}
]
This is my function as it currently is.
$scope.createRow = function(){
angular.forEach(angular.element("input"), function(value, key){
$scope.td.push($(value).val());
});
}
Any help or pointers would be greatly appreciated as I am just getting my head round the angular way
Doing this isn't hard... but before I give you a gun to shoot yourself in the foot, just to say that I think it would be beneficial to explain WHY you want structure in that other format you are mentioning. You seem to have lots of data repetition and that's always a red flag.
Now for the code, you just need to create object before pushing it to the array like:
$scope.createRow = function(){
angular.forEach(angular.element("input"), function(value, key){
var obj = {
"header1": val + "-1",
"header2": val + "-2"
};
$scope.td.push(obj);
});
}
EDIT:
OK, so you are trying to add new row to the table. First of all, you shouldn't be doing angular.forEach, but rather those input elements in HTML should bind to existing scope object, like:
// obviously use better names than Input1Value
// I am here just giving you example
$scope.bindData = {
Input1Value: null,
Input2Value: null
};
// in HTML you will do
// <input ng-model="bindData.Input1Value" />
// <input ng-model="bindData.Input2Value" />
Now that you've eliminated that nasty angular.forEach you need to have some kind of event handler, for example when user clicks the button you want to add this object to the array to which table is data bound. Just be sure to clone the $scope.bindData object when you add it to array.
$scope.createRow = function(){
var newRowData = $scope.cloneObject($scope.bindData);
$scope.td.push(newRowData);
}
// http://heyjavascript.com/4-creative-ways-to-clone-objects/
// https://stackoverflow.com/questions/728360/most-elegant-way-to-clone-a-javascript-object
$scope.cloneObject = function(objToClone) {
var newObj = (JSON.parse(JSON.stringify(objToClone)));
}
To close this answer off - keep in mind, if you ever find yourself directly referencing HTML DOM elements in Javascript with AngularJS - you are doing something wrong. It's a nasty habit to eliminate, especially if you are coming from jQuery background (and how doesn't?), where everything is $("#OhHiThere_ElementWithThisId).
Obviously the main thread on this topic on StackOverflow is this one:
“Thinking in AngularJS” if I have a jQuery background?
However I find that it's too theoretical, so Google around and you may find better overviews like:
jQuery vs. AngularJS: A Comparison and Migration Walkthrough

Push JSON File to Firebase

I've got a large JSON file that I'd like to push to my Firebase. It's currently in a specific format that I'd like to slightly change when pushed.
My current JSON file looks a bit like this:
"item": [
{
"title": "Hernia Repair",
"dc:creator": "realph",
"content:encoded": "A hernia occurs when an internal part of the body pushes through a weakness in the muscle or surrounding tissue wall. Your muscles are usually strong and tight enough to keep your intestines and organs in place, but a hernia can develop if there are any weak spots.",
},
...
]
While my Firebase items look like this:
"services" : {
"-JfTLQsxlZr6W2JWwMMd" : {
"description" : "Hernia repair refers to a surgical operation for the correction of a hernia (a bulging of internal organs or tissues through the wall that contains itself.",
"title" : "Hernia Repair",
},
...
}
I'm trying to push each one of these items to the services object that's already set up in my Firebase. But I'd like to push each item to a new unique id (i.e. -JfTLQsxlZr6W2JWwMMd), just like it is in my Firebase object (above). I also want push the title to title and push content:encoded to description.
Is this even possible? Doing this would potentially save me a lot of time going forward.
Any help from someone that is familiar with this sort of thing would be appreciated. Thanks in advance!
Update
This is what I was thinking to do, but I don't believe it's wired up correctly. I'm getting back a unique key with the console.log, but no item is being added to the services object:
$scope.convertItems = function() {
for(var i=0; i < $scope.items.length; i++) {
var newService = {
title: title,
description: 'content:encoded'
};
}
var promise = ServiceService.add(newService);
promise.then(function(data) {
console.log(data.name());
});
};

Spotify List objects created from localStorage data come up blank

I'm working on a Spotify app and trying to create a views.List object from some stored information in our database. On initial load, a POST is made to get the necessary info. I store this in localstorage so each subsequent request can avoid hitting the database and retrieve the object locally. What's happening though is the List objects I create from localstorage data come up blank, while the POST requests work just fine.
Here is the snippet I'm using to create the list:
var temp_playlist = models.Playlist.fromURI(playlist.uri);
var tempList = new views.List(temp_playlist, function (track) {
return new views.Track(track, views.Track.FIELD.STAR |
views.Track.FIELD.NAME |
views.Track.FIELD.ARTIST |
views.Track.FIELD.DURATION);
});
document.getElementById("tracklist").appendChild(tempList.node);
playlist.uri in the first line is what I'm retrieving either from a POST or from localstorage. The resulting views.List object (tempList) looks identical in both cases except for tempList.node. The one retrieved from localstorage shows these values for innerHTML, innerText, outerHTML, and outerText in console.log:
innerHTML: "<div style="height: 400px; "></div>"
innerText: ""
outerHTML: "<div style="height: 400px; "></div>"
outerText: ""
Whereas the one retrieved via POST has the full data:
innerHTML: "<div style="height: 400px; "><a href="spotify:track:07CnMloaACYeFpwgZ9ihfg" class="sp-item sp-track sp-track-availability-0" title="Boss On The Boat by Tosca" data-itemindex="0" data-viewindex="0" style="-webkit-transform: translateY(0px); ">....
innerText: "3Boss On The BoatTosca6:082....
and so forth..
Any help would be greatly appreciated
Solved this.
I am using hide() and show() to render the tabs in my app. I was constructing the tracklist and then show()ing the div which led to a blank tracklist. If I simply show() the div and then construct the tracklist it works fine.
The reason (I think) it was working for POSTs is because the tracklist was retrieved from the database and the slightly longer loading time probably meant the tracklist was constructed after the div's show() executed. With localStorage I guess the tracklist was constructed before the div was even shown, leading to the error.
Using, the local storage, I did it this way :
sp = getSpotifyApi(1);
var m = sp.require("sp://import/scripts/api/models");
var v = sp.require("sp://import/scripts/api/views");
var pl;
pl = m.Playlist.fromURI(uri);
var player = new v.Player();
player.track = pl.get(0);
player.context = pl;
var list = new v.List(pl);
XXXXX.append($(list.node));
Hope, it will help, as it's working for me
I think I've actually managed to solve this and I think it's bulletproof.
Basically I was trying to solve this by trying to convince the API that it needed to redraw the playlist by hiding things/scrolling things/moving things which worked occasionally but never consistently. It never occurred to me to change the playlist itself. Or at least make the API think the playlist has changed.
You can do so by firing an event on the Playlist object.
var models = sp.require('$api/models');
...
// playlist is your Playlist object. Usually retrieved from models.Playlist.fromURI
playlist.notify(models.EVENT.CHANGE, playlist);
These are just standard Spotify functions and the list updates because it thinks something has changed in the playlist. Hope this helps someone!