• Joseph Murawski
  • NEWBIE
  • 10 Points
  • Member since 2017

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 5
    Questions
  • 11
    Replies
I'm not sure if this can be done but I thought I would ask.  

I have a lightning component I wrote to use in the global actions area.  It uses a search component doing the search on name.  This works great but not what the user wants.  I could re-write the lookup component to search on the requested field but then it is no longer a generic component which I want to avoid.  Instead I thought I would add a design element to allow for marking the field to search on.  

The problem is I added a design to the component asking for the field and now that it is complete, I find I do not know how to assign the value in the Global Actions section.
I use lightning:fileInput to upload a file.  It gets loaded into ContentDocument.  

I need to process the data in the file (excel) so I'm trying to use MetadataService to move it to StaticResource and unzip as talked about in https://andyinthecloud.com/2012/11/04/handling-office-files-and-zip-files-in-apex-part-1/ 
I have the upload working, and when I get the data from contentDocument I can create an attachment that works so I know I'm getting the right data, but when I try creating the staticResource it does not work. 

I'm including the code i am using to do the conversion.  It uses the metadataService talked about in the above listed blog.  I desperately need help figuring out why I am getting url page header data in the blob instead of actually data when the attachment seems to be getting the data.
 
@AuraEnabled
    public static object getFileId(string fName)
    {
        ContentVersion cv = new ContentVersion();
        string fName2 = fName.Replace('.xlsx','');
        ///sfc/servlet.shepherd/version/download/contentversionid
        HttpResponse res = CommonFunctions.getToken();
        String tokenResp = res.getBody();
        String tokenStr = CommonFunctions.parseJSONStatic(tokenResp,'access_token');
        
        cv = [Select Id,contentbodyid,contentdocumentid from ContentVersion Where Title = :fName2 LIMIT 1];
        string hostURL = CommonFunctions.returnHostEnv();  
		//string cURL = hostURL + '/sfc/servlet.shepherd/version/download/' + cv.id;      
		string cURL = hostURL + '/servlet/servlet.FileDownload?file=' + cv.id;
        system.debug('CURL: ' + cURL);
        HTTPResponse resp = new httpResponse();
        HttpRequest reqst = new HttpRequest();
        reqst.setEndpoint(cURL);
        reqst.setMethod('GET');
        reqst.setHeader('Content-Type','application/txt;charset=base64');
        reqst.setHeader('Authorization','Bearer '+tokenStr);  
        reqst.setTimeout(120000);
        Http http1 = new Http();
        resp = http1.send(reqst); 
        blob b = resp.getBodyAsBlob();
        
        /*  Different tests.  None worked
        string strB = b.toString();
        string strC = EncodingUtil.urlEncode(strB, 'utf-8');
        system.debug('XX strFile: ' + strC);
        string strFile = EncodingUtil.urlEncode(resp.getBody(), 'utf-8');
*/
        
        //blob asFile = resp.getBodyAsBlob();
        //string strFile = EncodingUtil.base64Encode(asFile);
        //strFile = EncodingUtil.urlEncode(strFile, 'utf-8');
        //system.debug('XX strFile: ' + strFile);
		//blob asFile2 = blob.valueOf(strFile);      
        
        // At this point we have the file data inside a string
        // Now we need to store it as a resource so it can be unzipped
        // 
        // As a test, try creating an attachment of the file to see what we are actually getting
 		// The following works to grab the file and add into an attachment, so we are getting the correct data from the rest api
        //Attachment oAttachment = new Attachment();
        //oAttachment.parentId = 'a0s36000002wQGMAA2';
        //oAttachment.Body = b;
        //oAttachment.Name = 'TestFile';
        //oAttachment.ContentType = 'application/xlsx';
        //system.debug('XX oAtt.BlobSize: ' + oAttachment.Body.size());
        //insert oAttachment;
        
        MetadataService.MetadataPort service = MetadataService.createService();
        MetadataService.StaticResource staticResource = new MetadataService.StaticResource();
        staticResource.fullName = 'WorkloadPerformanceXLSX';
        //staticResource.contentType = 'application/xlsx';
        staticResource.contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
        //staticResource.contentType = 'application/txt';
        staticResource.cacheControl = 'public';
        // content needs to be a base64 string.
        staticResource.content = b.toString();
        staticResource.description = 'Upload and process workload performance data';
        List<MetadataService.SaveResult> results = service.createMetadata(new MetadataService.Metadata[] { staticResource });
        
        // Process the data here
        //PageReference somefileRef = new PageReference('/resource/folder/' + staticResource.fullName );
		//Blob contentAsBlob = somefileRef.getContent();
		//String contentAsText = contentAsBlob.toString();
        //system.debug('XX XML Content: ' + contentAsText);

        // Clean it up now
        // Delete Static Resource
        //MetadataService.MetadataPort dele_service = MetadataService.createService();
        //List<MetadataService.DeleteResult> dele_results = dele_service.deleteMetadata('StaticResource', new String[] { staticResource.fullName });
        
        // Delete File Content   
        ContentDocument cd = [Select Id from ContentDocument Where id = :cv.contentdocumentid LIMIT 1];
        delete cd;

 
I have a custom lightning component that uses:  
<input type="file" class="slds-file-selector__input slds-assistive-text" 
                                   onchange="{!c.saveFile}" aura:id="file"
                                   accept="image/png;image/jpg;image/gif" id="file-upload-input-01" 
                                   aria-labelledby="file-selector-primary-label file-selector-secondary-label" />
to upload a file (Attaching code for saveFile function).
My problem is that when I use the component on account record and then switch to another record, when I process the upload on the other record it still uses the account record ID in the save routine.  I have checked to make sure the component recordId from the hasRecordId is loading correctly.  
 
ComponentController:
    saveFile: function(component,event,helper) {
        helper.showSpinner(component,"spinner");
		helper.uploadMe(component,event,helper);  
    },

Helper:
    upload: function(component, file, base64Data, helper,event) {  
        var action = component.get("c.saveAttachment"); 
        action.setParams({
            parentId: component.get("v.recordId"),
            fileName: file.name,
            base64Data: base64Data, 
            contentType: file.type
        });
        console.log("c.saveAttachment time start: " + Date.now())
        action.setCallback(this, function(a) {
        console.log("c.saveAttachment time callback returned: " + Date.now())
            var state = a.getState();
            if (state === "SUCCESS") {
		        console.log("c.saveAttachment time callback success: " + Date.now())
                helper.hideSpinner(component,"spinner");
                component.set("v.message", "");
                component.set('v.deleteIconClass', 'slds-float--right slds-p-right_small');
                helper.ToastMe(component, event, helper, "success", "Image uploaded");
                $A.get('e.force:refreshView').fire();
            }
            else {
                component.set("v.message", "");
                helper.ToastMe(component, event, helper, "error", "Image Upload Failed");
            }
        });
        console.log("c.saveAttachment time callback queued: " + Date.now())
        $A.enqueueAction(action); 
    },
    uploadMe: function(component,event,helper)
    {
        var fileInput = component.find("file").getElement();
    	var file = fileInput.files[0];
        var fSize = 0;

        if (!file) return;

        if (!file.type.match(/(image.*)/)) {
            helper.ToastMe(component, event, helper, "error", "Image file not supported");
  			return;
		}
        if (file.size > this.MAX_FILE_SIZE_SM) {
			fSize = 1;
            helper.ToastMe(component, event, helper, "error", "File needs to be less than 1024 KB.  Current size: " + file.size);
            return;
            
        }
        
        var self = this;
        var fr = new FileReader();
        fr.onloadend = function() {
            var dataURL = fr.result;
            component.set("v.pictureSrc", dataURL);
            helper.upload(component, file, dataURL.match(/,(.*)$/)[1],helper,event);
            
        };
        fr.readAsDataURL(file);
    },

 
I have created a lightning component that uses 
<div class="slds-truncate" title="{!v.fieldLabel}">
                                <label class="slds-form-element__label">{!v.fieldLabel}</label> <br />
                                <ui:inputSelect aura:id="inputCell" class="slds-input" value="{!v.fieldData}">
                                    <aura:iteration items="{!v.options}" var="statusOption">   
                                        <ui:inputSelectOption text="{!statusOption.value}" label="{!statusOption.label}" />                                       
                                    </aura:iteration>
                                </ui:inputSelect>
                            </div>
to select from a picklist value.  In the save routine I end with $A.get('e.force:refreshView').fire(); to refresh all the components on the page.  When this takes place, the selected value in the picklist is no longer selected and shows the first value in the list. 
I tried re-calling the doInit function but it fires before the refresh is complete and does not fix this.

Any ideas on what I can do to fix this issue?
 
We have a process that pushes data to wave.  I can add fields to the datasource and to the metadata without a problem, but when I try to remove a field it generates an error.  
What I do is remove the field from the .csv file, and remove the field from the .json metadata then do the push.   Is there something else I need to do?

Joe
I use lightning:fileInput to upload a file.  It gets loaded into ContentDocument.  

I need to process the data in the file (excel) so I'm trying to use MetadataService to move it to StaticResource and unzip as talked about in https://andyinthecloud.com/2012/11/04/handling-office-files-and-zip-files-in-apex-part-1/ 
I have the upload working, and when I get the data from contentDocument I can create an attachment that works so I know I'm getting the right data, but when I try creating the staticResource it does not work. 

I'm including the code i am using to do the conversion.  It uses the metadataService talked about in the above listed blog.  I desperately need help figuring out why I am getting url page header data in the blob instead of actually data when the attachment seems to be getting the data.
 
@AuraEnabled
    public static object getFileId(string fName)
    {
        ContentVersion cv = new ContentVersion();
        string fName2 = fName.Replace('.xlsx','');
        ///sfc/servlet.shepherd/version/download/contentversionid
        HttpResponse res = CommonFunctions.getToken();
        String tokenResp = res.getBody();
        String tokenStr = CommonFunctions.parseJSONStatic(tokenResp,'access_token');
        
        cv = [Select Id,contentbodyid,contentdocumentid from ContentVersion Where Title = :fName2 LIMIT 1];
        string hostURL = CommonFunctions.returnHostEnv();  
		//string cURL = hostURL + '/sfc/servlet.shepherd/version/download/' + cv.id;      
		string cURL = hostURL + '/servlet/servlet.FileDownload?file=' + cv.id;
        system.debug('CURL: ' + cURL);
        HTTPResponse resp = new httpResponse();
        HttpRequest reqst = new HttpRequest();
        reqst.setEndpoint(cURL);
        reqst.setMethod('GET');
        reqst.setHeader('Content-Type','application/txt;charset=base64');
        reqst.setHeader('Authorization','Bearer '+tokenStr);  
        reqst.setTimeout(120000);
        Http http1 = new Http();
        resp = http1.send(reqst); 
        blob b = resp.getBodyAsBlob();
        
        /*  Different tests.  None worked
        string strB = b.toString();
        string strC = EncodingUtil.urlEncode(strB, 'utf-8');
        system.debug('XX strFile: ' + strC);
        string strFile = EncodingUtil.urlEncode(resp.getBody(), 'utf-8');
*/
        
        //blob asFile = resp.getBodyAsBlob();
        //string strFile = EncodingUtil.base64Encode(asFile);
        //strFile = EncodingUtil.urlEncode(strFile, 'utf-8');
        //system.debug('XX strFile: ' + strFile);
		//blob asFile2 = blob.valueOf(strFile);      
        
        // At this point we have the file data inside a string
        // Now we need to store it as a resource so it can be unzipped
        // 
        // As a test, try creating an attachment of the file to see what we are actually getting
 		// The following works to grab the file and add into an attachment, so we are getting the correct data from the rest api
        //Attachment oAttachment = new Attachment();
        //oAttachment.parentId = 'a0s36000002wQGMAA2';
        //oAttachment.Body = b;
        //oAttachment.Name = 'TestFile';
        //oAttachment.ContentType = 'application/xlsx';
        //system.debug('XX oAtt.BlobSize: ' + oAttachment.Body.size());
        //insert oAttachment;
        
        MetadataService.MetadataPort service = MetadataService.createService();
        MetadataService.StaticResource staticResource = new MetadataService.StaticResource();
        staticResource.fullName = 'WorkloadPerformanceXLSX';
        //staticResource.contentType = 'application/xlsx';
        staticResource.contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
        //staticResource.contentType = 'application/txt';
        staticResource.cacheControl = 'public';
        // content needs to be a base64 string.
        staticResource.content = b.toString();
        staticResource.description = 'Upload and process workload performance data';
        List<MetadataService.SaveResult> results = service.createMetadata(new MetadataService.Metadata[] { staticResource });
        
        // Process the data here
        //PageReference somefileRef = new PageReference('/resource/folder/' + staticResource.fullName );
		//Blob contentAsBlob = somefileRef.getContent();
		//String contentAsText = contentAsBlob.toString();
        //system.debug('XX XML Content: ' + contentAsText);

        // Clean it up now
        // Delete Static Resource
        //MetadataService.MetadataPort dele_service = MetadataService.createService();
        //List<MetadataService.DeleteResult> dele_results = dele_service.deleteMetadata('StaticResource', new String[] { staticResource.fullName });
        
        // Delete File Content   
        ContentDocument cd = [Select Id from ContentDocument Where id = :cv.contentdocumentid LIMIT 1];
        delete cd;

 
I have a custom lightning component that uses:  
<input type="file" class="slds-file-selector__input slds-assistive-text" 
                                   onchange="{!c.saveFile}" aura:id="file"
                                   accept="image/png;image/jpg;image/gif" id="file-upload-input-01" 
                                   aria-labelledby="file-selector-primary-label file-selector-secondary-label" />
to upload a file (Attaching code for saveFile function).
My problem is that when I use the component on account record and then switch to another record, when I process the upload on the other record it still uses the account record ID in the save routine.  I have checked to make sure the component recordId from the hasRecordId is loading correctly.  
 
ComponentController:
    saveFile: function(component,event,helper) {
        helper.showSpinner(component,"spinner");
		helper.uploadMe(component,event,helper);  
    },

Helper:
    upload: function(component, file, base64Data, helper,event) {  
        var action = component.get("c.saveAttachment"); 
        action.setParams({
            parentId: component.get("v.recordId"),
            fileName: file.name,
            base64Data: base64Data, 
            contentType: file.type
        });
        console.log("c.saveAttachment time start: " + Date.now())
        action.setCallback(this, function(a) {
        console.log("c.saveAttachment time callback returned: " + Date.now())
            var state = a.getState();
            if (state === "SUCCESS") {
		        console.log("c.saveAttachment time callback success: " + Date.now())
                helper.hideSpinner(component,"spinner");
                component.set("v.message", "");
                component.set('v.deleteIconClass', 'slds-float--right slds-p-right_small');
                helper.ToastMe(component, event, helper, "success", "Image uploaded");
                $A.get('e.force:refreshView').fire();
            }
            else {
                component.set("v.message", "");
                helper.ToastMe(component, event, helper, "error", "Image Upload Failed");
            }
        });
        console.log("c.saveAttachment time callback queued: " + Date.now())
        $A.enqueueAction(action); 
    },
    uploadMe: function(component,event,helper)
    {
        var fileInput = component.find("file").getElement();
    	var file = fileInput.files[0];
        var fSize = 0;

        if (!file) return;

        if (!file.type.match(/(image.*)/)) {
            helper.ToastMe(component, event, helper, "error", "Image file not supported");
  			return;
		}
        if (file.size > this.MAX_FILE_SIZE_SM) {
			fSize = 1;
            helper.ToastMe(component, event, helper, "error", "File needs to be less than 1024 KB.  Current size: " + file.size);
            return;
            
        }
        
        var self = this;
        var fr = new FileReader();
        fr.onloadend = function() {
            var dataURL = fr.result;
            component.set("v.pictureSrc", dataURL);
            helper.upload(component, file, dataURL.match(/,(.*)$/)[1],helper,event);
            
        };
        fr.readAsDataURL(file);
    },

 
I have created a lightning component that uses 
<div class="slds-truncate" title="{!v.fieldLabel}">
                                <label class="slds-form-element__label">{!v.fieldLabel}</label> <br />
                                <ui:inputSelect aura:id="inputCell" class="slds-input" value="{!v.fieldData}">
                                    <aura:iteration items="{!v.options}" var="statusOption">   
                                        <ui:inputSelectOption text="{!statusOption.value}" label="{!statusOption.label}" />                                       
                                    </aura:iteration>
                                </ui:inputSelect>
                            </div>
to select from a picklist value.  In the save routine I end with $A.get('e.force:refreshView').fire(); to refresh all the components on the page.  When this takes place, the selected value in the picklist is no longer selected and shows the first value in the list. 
I tried re-calling the doInit function but it fires before the refresh is complete and does not fix this.

Any ideas on what I can do to fix this issue?
 
Hi:
Since the Winter 19 release, I am getting the above error when I run any unit test that modified a user record.

We are using the User License type: Overage Authenticated Website

I cannot locate the permission "Edit Self-Service Users" I turned off the enhanced user management to look for it and also tried giving my Users a permission set with all permissions under Users section.

Doing some research on previous posts about the  "Edit Self-Service Users" that what was recommended.

Thanks in advance,
We have enabled the Lightning connect and defined an External Data Source for Lightning Connect - Odata 2.0 Adapter and the External Object records are loaded from Informatica. The functionality basically displays all the external object records related to an Account (External object is related to Account - indirect lookup relationship), on the Account detail page as an inline VF page. When the external object records are queried, in the background a REST callout is made. So the Test class needs to use a Test.setMock() method to set a mock response. Here is the code snippet that I'm using:

 static testMethod void PositiveTestCase() {
// test user - currentUser
system.runAs(currentUser){

//Setup Test Data
//Mock response
String testResp = 'CUSTOMER_SALES_HISTORY__x:{DisplayUrl=TEST,CUSTOMER_SALES_HISTORY_IID__c=TEST,ExternalId=TEST,SAP_CUSTOMER_NUMBER__c = 0000001003, PRODUCT_LINE__c  = LINEA, PRODUCT_NAME__c =PRD1 PRODUCT_TYPE__c = TYPEA}, CUSTOMER_SALES_HISTORY__x:{DisplayUrl=TEST1,CUSTOMER_SALES_HISTORY_IID__c=TEST1,ExternalId=TEST1,SAP_CUSTOMER_NUMBER__c =1234, PRODUCT_LINE__c  = LINEA, PRODUCT_NAME__c =PRD2 PRODUCT_TYPE__c = TYPEB}';

//Test class that implements HttpCalloutMock and returns a reusable response
Test_ReusableMockResponse fakeResponse = new Test_ReusableMockResponse(200,'SUCCESS',testResp, null);

Test.setMock(HttpCalloutMock.class, fakeResponse);
Test.startTest();
//set the standard Controller to the test Account created
ApexPages.StandardController std = new ApexPages.StandardController(testAccount);
InlineOrderHistoryViewController controllerInstance = new InlineOrderHistoryViewController(std);
Test.stopTest();
}
}

 
For a straightforward - web service built on REST, this mock response approach should ideally work. Considering the mock response as the real time response received, the unit test case scenario should cover the code.
But in this case, the mock response is not considered as the real time response in the unit test method and all the subsequent lines of code aren't covered.
Also, the Test.setMock() does help in overcoming -' Test methods to not support the WebService Callout' error. So I'm totally convinced that I need to cover this the way we cover the code involving web service callouts.

Please let me know if you have a workaround for this

Thanks,
Sirisha Kodi