Accessing one element in an array using Firebase-collection in polymer - firebase

I am trying to use the new firebase-collection introduced in Polymer 1.0 to access one element in an array in my firebase nosql database. However, I get back nothing.
Here's a snippet of my code:
<firebase-collection data="{{testItem}}"
location="https://<firebase-path>.firebaseio.com/testItems/0/">
</firebase-collection>
<section class="layout vertical center-center" id="moreInfo">
<div class="layout vertical">
<test-block art="{{testItem}}"></test-block>
</div>
</section>
Notice how I am trying to access item at index 0 in https:///firebaseio.com/testItems. Is it even possible to access it using firebase-collection? Or should we just fetch the collection and then iterate?

Yeah that approach won't work since the data property expects/is populated with an array of data from your DB. I believe if you set the location to "https://.firebaseio.com/testItems" that you can reference the first item in the data array like so:
<test-block art="{{testItem.0}}"></test-block>
Another approach if you know the Firebase key of the item you want would be to use firebase-collection's getByKey method in your Javascript.

Related

VUEJS: Is it possible to process/modify data retrieved through v-for before displaying?

Hello I am extremely new to web application development / javascript in general. Only gave myself crash courses from udemy videos for the past 4 months.
For my web application, I am retrieving data from a database through my server-side backend with axios. I have a logRepository Array where the retrieved data is pushed.
data() {
return {
logRepository: [],
}
},
created() {
axios.get('/myrestapiroute', {
headers: {
'Authorization': `Bearer ${this.$store.state.token}`
},
params: {
userId: this.userId
}
})
.then(res => {
const data = res.data.logs
this.dataCheck = data
for(let key in data) {
const log = data[key]
log.id = key
this.logRepository.push(log)
}
})
On my template, I used v-for to loop through all the retrieved data elements:
<div ..... v-for="(log,index) in logRepository" :key="index">
With the v-for in place, one example of how I display my data as such in a paragraph tag. The format is due to how the data was structured.
<p style="text-align: justify;">
{{ log.logId.jobPerformed }}
</p>
The problem arises when I try to apply styling to the text. As you can see above, I would like to use text-align: justify. I also wanted to keep the whitespace as how it was input by the user through the use of white-space: pre-wrap.
(https://i.imgur.com/dwaJHT9.png)
But the problem is these two styles do not work together well. As can be seen below in the picture, if I use justify on its own, it behaves normally (Except that whitespace is lost). However, if I combine both text-align:justify and white-space: pre-wrap, the text end up justified with spacing, but aligned in a weird way.
(https://i.imgur.com/DQSfOya.png)
For short entries, they begin with weird indentation when the starting side should be aligned to the left of the column. The issue appears to be more than simply whitespaces at the start as I have tried .trim() as suggested by a contributor.
(https://i.imgur.com/uwysk9X.png)
I tried to tweak the CSS around, with text-align-last, text-align-start, direction: ltr, pre-tags etc. But it just does not work properly. Suggestions from other SO pages recommended that the data be processed by performing a string replace of all \n to br before displaying.
Is it possible to perform processing for individual data obtained from v-for before displaying or it has to be done to the array using computed property?
Since my data is to be fetched from a database, I am confused on how to achieve the pre-processing of data, since my array size will dynamic and differ for each user.
What would be the most optimal way to achieve pre-processing of data before displaying for such case?
This image below is how my Array of Object (logRepository) looks like. The format is largely due to mongoDB schema.
(https://i.imgur.com/7SilcF7.png)
======= Solution =======
I modified the object variables in my .then block and performed string replace for all \n characters to tags.
https://i.imgur.com/EtLX2tg.png
With that my display no longer requires the "white-space: pre-wrap" styling. However, since I was previously using string interpolation to display my data the tags were treated as plain text.
https://i.imgur.com/zUbNZbI.png
I had to modify the tags to use v-html binding to display the data as htmltext so that would work. The difference can be seen in the last picture.
https://i.imgur.com/sCTsCV4.png
Thanks for helping me on this since I am very new to javascript.
There are a number of patterns you could use here to pre-process your data.
Process your data in the then function you have created
Wrap the data in functions within the {{ ... }} blocks in the template
Create a component that is used as the element that the v-for loop iterates over which displays a computed value
Use a computed value as the source array of the v-for directive in the main template. This is often done using a processing function mapped to the source data, as in log.map( data => data.logId.jobPerformed.trim()

Meteor Easy-Search including two field names into autosuggest box

So I have an easy-search template as such:
{{> EasySearch.Autosuggest index=PlayersIndex labelField="Player" valueField="Team"}}
My index is defined as:
export const PlayersIndex = new Index({
collection: Stocks,
fields: ['Player', 'Team'],
engine: new MinimongoEngine(),
});
And I want the autosuggest box to display both the Player and the Team. Right now it just shows the Player. How can I achieve this?
You should first visit the autosuggest's documentation which is pretty short. From there it's pretty clear that only the first member of the fields array (in your case "Player") is chosen as the value to present when searching. To change this behavior you can pass a different template through the renderSuggestion parameter that EasySearch.Autosuggest seems to accept. By default it's using the
EasySearch_Autosuggest_DefaultRenderSuggestion template which you can find here. You can just create your own template in one of your files
<template name="playerTeamAuto">
<div>
<span class="autosuggest-title">
<span class="name">{{label}}</span>
<span class="teamName">{{doc.Team}}</span>
</span>
</div>
</template>
This will work only for your set of results where the returned documents would have a guranteed field of Team that's why we can access it through the doc variable. This comes from the object that the template is rendered with here on this specific line. As you can see it has all the data fields returned through the form of item, as even the label is gotten from there. I've added a between the player and team name, but you can format them any way you want.

Adding fields dynamically to Share form

I want to add a text field for each file that is added to the attached package items in alfresco to write notes regarding each file, is it possible to do?
I have implemented something that could be reused for your use case.
You can define a property with multiple values that will contain the list of notes associated with each attachment.
There is a simple trick to post a property with multiple values: add "[]" to the name of the property. For example:
<input id="template_x002e_edit-metadata_x002e_edit-metadata_x0023_default_prop_someco_notes_0"
name="prop_someco_notes[]"
tabindex="0"
type="text"
value="Meeting minutes"
title="Notes"
noderef="workflow://...."
>
<input id="template_x002e_edit-metadata_x002e_edit-metadata_x0023_default_prop_someco_notes_1"
name="prop_someco_notes[]"
tabindex="1"
type="text"
value="Meeting minutes"
title="Notes"
noderef="workflow://...."
>
As you can see, the name of the input ends with []. Both input textfields have the same name.
The Alfresco Form Engine will consider these two inputs as the value for the property with multiple values: "someco:notes".
The bigger problem is that you need to generate this html with some smart javascript and free marker template.
You can write a custom free marker template to render the initial html: if a user opens a task on which documents have been already attached, you will need to generate the list of inputs using a custom control (you can of course start from textfield.ftl).
It won't be easy to generate the initial list because unfortunately Alfresco returns the list of values as a single comma separated value.
You can customise the webscript that injects the model in the free marker template "org.alfresco.web.scripts.forms.FormUIGet" to pass an array instead of a csv.
A quicker and dirtier solution is to split the csv value. In share-config-custom.xml, you can specify what textfield.ftl show use as a separator instead of the comma.
When a user adds/remove elements from the package, you can intercept the update and add/remove the correspondent note. Notice that I have added the filed "noderef" to each input so it is possible to know the relation between the notes and the nodes in the package.
UPDATE:
For the associations (used for example to define the package in a workflow task), Share uses a javascript library called "object finder" (or "object picker"). This library fires an event called "formValueChanged" that you can intercept:
YAHOO.Bubbling.fire("formValueChanged",
{
eventGroup: this,
addedItems: addedItems,
removedItems: removedItems,
selectedItems: selectedItems,
selectedItemsMetaData: Alfresco.util.deepCopy(this.selectedItems)
});

Looking for suitable way to customize Alfresco share

I have a unique requirement by my company to have a page for each sub-folder in a particular folder of alfresco share. So basically there would be hundreds of sub-folders and corresponding hundreds of pages representing it. The page for that folder should have links to its sub-folders and maybe even documents within it in the form of a collapsible list as shown:
Folder 1
-Category 1
Doc 1
Doc 2
-Category 2
-Sub-category 1
doc 3
I want to have something like shown above on one side of the page and the other side should have all the recent activities related to the folder, like who added a doc, what edits were made, were there any comments, etc. I searched a lot related to this but I am not sure if alfresco supports this kind of customization. I found some really good tutorials on creating custom pages in share using JSON widgets but don't think it would help in this case. Other option would be generate an html page for every new folder created and populate it using javascript. But this method won't have much flexibility in terms of designing the page. Does anyone know of a better approach or idea for this requirement ? I would really appreciate any thoughts on this.
I'll just write it as an answer (relating to my previous comment). I've done something similar in this way (using the link provided in the comments:
create a simple alfresco web script that returns a json of what you need (in you case recently modified documents). I've done it with listing a folder, this is mywebscript.get.json.ftl:
{
"docprop" : [
<#list companyhome.childByNamePath["MyFolder"].children as child>
{
"name" : "${child.properties.name}" ,
"author" : "${child.properties["cm:author"]}",
"CreatedDate" : "${child.properties.created?datetime}"
}
<#if child_has_next> , </#if>
</#list>
]
}
create Share widget controller file where you call this web script with retrievedoc.get.js:
var connector = remote.connect("alfresco");
var data = connector.get("/mywebscript.json"); //the url is declared in your `mywebscript.get.desc.xml`
// create json object from data
var result = eval('(' + data + ')');
model.docprop = result["docprop"];
create Share widget presentation template with retrievedoc.get.html.ftl:
<div class="dashlet">
<div class="title">${msg("header.retrievedocTitle")}</div>
<div class="body retrievedoc">
<table>
<tr>
<th>Name: </th>
<thAuthor: </th>
<th>Created: </th>
</tr>
<#list docprop as t>
<tr>
<td>${t.name}</td>
<td>${t.author}</td>
<td>${t.CreatedDate}</td>
</tr>
</#list>
</table>
</div>
You then need to register your widget in Share, and use it in your dashboard. It will call the Alfresco script and populate the widget with the results. Obviously you need to change your Alfresco script to return recent activities (you could make a query like: all documents modified in the last 24 hours, or something like this. But the method is the same.
Hope it helps.
You could create new folder tree component in alfresco share to meetup your requirement.
Alfresco share page madeup of multiple comoponents which are kind of self sufficient components in terms of data and dependancy(Excluding few alfresco common dependancy).
Here is the outline for the approch
Create one folder tree comopnent in alfresco, which will be nothing
but a webscript which render related webscripts output on page in
which component is included.
Create one Dynamic YUI tree with some dummy data and check weather
you are able to generate or not.(Just to make sure you have all
depenency included).
Create one data webscript on repository side which will fetch folder
structure related data from repository.Make it in such way that if
you pass folder noderef if will return all childrens under
that.There is one similar webscript also avilable out of box may be
you could reuse that.
Once you have that webscript working properly call that repository
webscript to populate your dynamic tree and remove all dummy data.
I hope this gives you good starting point.
You will certainly find documentation for each of these steps.

Error: ngRepeat:dupes Duplicate Key in Repeater

I have a column(I call it in my codebehind as keyW) in a stored procedure that returns this value
[{key:138},{key:139},{key:140},{key:141},{key:142},{key:143},{key:145},{key:146},{key:148}]
on my design view I have put the code like this
<div id="allerg" ng-repeat="allerg in recipe.keyW">
{{allerg.key}}
</div>
When I run my page it returns the duplicate key error. I am not sure what is wrong. I am returning the right values as what I have read in the ng-repeat documentation
thank you in advance
EDIT: I have also tried the track by $index. It removes the error but still doesn't display the values.
Try changing your div ID to something other than allerg
If your array contains int add "track by $index" to your code.
<div id="allerg" ng-repeat="allerg in recipe.keyW track by $index">
{{allerg.key}}
</div>

Resources