Using a VO in actionscript between classes - actionscript-3

In my class, I built a Weather VO (Visual Object) and now need to use it for another class.
How would I use it to modify the values of the text field in my second class? I attempted using getters and setters to no avail.
First Page:
vo=new WeatherVO();//Visual Object for the weather data
vo.city = _xmlData.channel.ns1::location.#city+", "+_xmlData.channel.ns1::location.#region;//city, st
vo.currentTemp = _xmlData.channel.item.ns1::condition.#temp;
vo.currentCondition = _xmlData.channel.item.ns1::condition.#text;
vo.currentCode = _xmlData.channel.item.ns1::condition.#code;
vo.sunrise = _xmlData.channel.ns1::astronomy.#sunrise;
vo.sunset = _xmlData.channel.ns1::astronomy.#sunset;
Second page:
public function set vo(value:WeatherVO):void
{
_weather=value;
}
public function get vo():WeatherVO
{
return _weather;
}

Your getters and setters should be methods of the WeatherVO class that aid in the modification and retrieval of properties within that class. With the limited code sample you have provided, my recommendation is to pass the weather data through your WeatherVO constructor like so.
public function WeatherVO(_city:String, _currentTemp:String, _currentCondition:String, _currentCode:String, _sunrisde:String, _sunset:String) {
city = _city;
currentTemp = _currentTemp;
currentCondition = _currentCondition;
currentCode = _currentCode;
sunrise = _sunrise;
sunset = _sunset;
}
//Here is an example getter and setter for the city value.
public function get City() {
return city;
}
public function set City(_city:String) {
city = _city;
}

Related

call function of class on instance of class

I have some code that generates answers based on the user input. But in somecases i need to update the values later by calling SetAnswers But when i compile my code i get the following error:
NullReferenceException: Object reference not set to an instance of an object
I get this error on the line marked by the arrow.
See below for my code:
public class Generate_Questions : MonoBehaviour{
public Question q5, q4;
void Start(){
q4 = create_question("Select object to edit", EXTERNAL);
Visual_Question vq1 = new Visual_Question(1, q4, new vector(1,1,1), Ui, Canvas);
vq1.draw_question();
}
void Update(){
}
public class Visual_Question : Generate_Questions{
public Visual_Question(int order_id, Question q, Vector2 loc, Dictionary<string, RectTransform> ui, RectTransform canvas){
}
public void draw_question(){
q4.SetAnswers(new Answer[]{ <--------- this generates the error.
new Answer(null, "Select an option")
});
}
}
public class Question{
public string text;
public int answers_loc;
public List<Answer> answers;
public Question(string q_text, int answers_loc){
answers = new List<Answer>();
this.text = q_text;
this.answers_loc = answers_loc;
}
public void SetAnswers(Answer[] c_answers){
foreach(Answer answer in c_answers){
this.answers.Add(answer);
}
}
public bool CheckIfAnswersAvailable(){
if(answers.Count > 0){
return true;
}else{
return false;
}
}
public int QuestionLocation(){
return answers_loc;
}
}
public Question create_question(string text, int a_type){
Question Q = new Question(text, a_type);
return Q;
}
public interface IAnswer{
string GetText();
string GetDataType();
object GetValue();
Question GetNextQuestion();
}
public class Answer : IAnswer{
public string text;
public Question next = null;
public int? action = null;
public Element obj = null;
public string property = null;
public float? value = null;
public Answer(Question next, string text){
this.text = text;
this.next = next;
}
public Answer(Question next, string text, Element obj, int? action){
this.action = action;
this.text = text;
this.next = next;
this.obj = obj;
}
public Answer(Question next, string text, Element obj, int? action, string property, float? value){
this.action = action;
this.next = next;
this.text = text;
this.obj = obj;
this.property = property;
this.value = value;
}
public string GetText(){
return text;
}
public string GetDataType(){
throw new System.NotImplementedException();
}
public object GetValue(){
return value;
}
public Question GetNextQuestion(){
return next;
}
}
}
how would i go about fixing this problem? I am a complete newbie to c#. So my question may be already answered but i just dont know what i am looking for.
I assume that IAnswer[] is an interface and since you are trying to initialize an abstract object you get that runtime exception
NullReferenceException: Object reference not set to an instance of an object
if you want to create instance of IAnswer object you have to restructure it like class or structure.
Your class Visual_Question derives from Generate_Questions, so the member q4 that you use en draw_question is not initialized. This is not the member of Generated_Questions but a member of Visual_Question that is not initialized.
In Generate_Questions you are creating a new instance of Visual_Question and then immediately calling draw_question on that new instance. You now have 2 instances of a question (both derive from Generate_Questions), but only one of them has had the Start method, which initializes q4 called. If, however, you attempt to call Start from your second instance, you're going to find yourself in an infinite series of recursive calls and quickly crash with a different error (a stack overflow in this case).
One issue with the current code is that Generate_Questions sounds more like an action than a class. I'd suggest removing the inheritance from Visual_Question and make that an interface that you would implement on Question. Question should probably have the create_question method removed. That probably belongs in a MonoBehavior script (technically it's a factory method -- look up the factory pattern -- I'm not going to go into it here since this is a beginner topic).
Something like (obviously not complete):
public class Generate_Questions : MonoBehaviour
{
private IVisualQuestion q4;
void Start()
{
q4 = new Question("Select object to edit", EXTERNAL);
q4.DrawQuestion(new vector(1,1,1), Ui, Canvas)
}
void Update() {}
}
public interface IVisualQuestion
{
void DrawQuestion(Vector2 loc, Dictionary<string, RectTransform> ui, RectTransform canvas);
}
public class Question : IVisualQuestion
{
// ... insert the Question constructor and code here ...
// Implement VisualQuestion interface
public void DrawQuestion(Vector2 loc, Dictionary<string, RectTransform> ui, RectTransform canvas)
{
this.SetAnswers(new Answer[]{new Answer(null, "Select an option")});
}
}
In general, you probably don't need inheritance. As you learn more C#, you'll discover that when inheritance is going to help it will be clear. More often than not, using an interface is a far better and flexible approach. As a commenter noted, you probably don't want to inherit from MonoBehavior. You really only need that for classes that the Unity Engine is going to directly handle.
Another note: the convention in C# is to name methods, variables, etc. in PascalCase, not using underscores to separate words.

convert class to object actionscript 3

I`m tring to covert class to json.
The class is:
package com.globalData{
public class userSite {
private var uID:int,uName:String,uSocket:int,uZone:int,uRoom:int;
public function user(ID:int,Name:String,ZoneID:int,RoomID:int,socketID:int){
uID = ID;
uName = Name;
uSocket = socketID;
uZone = ZoneID;
uRoom = RoomID;
}
public function getName():String{
return uName;
}
public function getID():int{
return uID;
}
public function getZoneID():int{
return uZone;
}
public function getRoomID():int{
return uRoom;
}
public function getSocket():int{
return uSocket;
}
}
}
Im tryed to do:
json(Object(roomVar));
But its not work (JSOn is function on the main class)
Im need to convert the class to json and send the json -> Socket
How can i do it?
There are a few issues with your code above:
It doesn't appear as though your userSite class has a constructor. Instead, you've opted to have a user function that takes in all of the initialization arguments
You're using functions where you should probably be using accessor methods, sometimes called a getter.
public function getName():String { return uName;} would become public function get name():String { return uName;}
Instead of calling getName(), you would access name as a property: instance.name
You're attempting to pass an Object to the JSON.decode method, this method expects a String. Something like "{ 'a':1, 'b':[1,2,3] }" would be an acceptable parameter. This would return an object with two properties a and b, a would contain the value 1, and b would contain an array with the elements 1, 2, and 3. What you are looking for is actually the JSON.encode method which accepts an Object and converts it to a String (which can be parsed as JSON).
I suggest you convert all of your getXYZ() functions to accessors, this will allow an instance of that class to be read as a collection of properties, which will in turn allow the JSON.encode function to create a JSON string object from it:
package com.globalData
{
public class UserSite {
private var uID:int,uName:String,uSocket:int,uZone:int,uRoom:int;
public function UserSite(ID:int,Name:String,ZoneID:int,RoomID:int,socketID:int):void{
uID = ID;
uName = Name;
uSocket = socketID;
uZone = ZoneID;
uRoom = RoomID;
}
public function get name():String{
return uName;
}
public function get ID():int{
return uID;
}
public function get zoneID():int{
return uZone;
}
public function get roomID():int{
return uRoom;
}
public function get socket():int{
return uSocket;
}
}
}
Usage:
var roomVar:UserSite = new UserSite(1, 'Name', 2, 3, 4);
trace(JSON.encode(roomVar as Object));
Output:
{"ID":1,"name":"Name","socket":4,"roomID":3,"zoneID":2}

How to add an extra property into a serialized JSON string using json.net?

I am using Json.net in my MVC 4 program.
I have an object item of class Item.
I did:
string j = JsonConvert.SerializeObject(item);
Now I want to add an extra property, like "feeClass" : "A" into j.
How can I use Json.net to achieve this?
You have a few options.
The easiest way, as #Manvik suggested, is simply to add another property to your class and set its value prior to serializing.
If you don't want to do that, the next easiest way is to load your object into a JObject, append the new property value, then write out the JSON from there. Here is a simple example:
class Item
{
public int ID { get; set; }
public string Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
Item item = new Item { ID = 1234, Name = "FooBar" };
JObject jo = JObject.FromObject(item);
jo.Add("feeClass", "A");
string json = jo.ToString();
Console.WriteLine(json);
}
}
Here is the output of the above:
{
"ID": 1234,
"Name": "FooBar",
"feeClass": "A"
}
Another possibility is to create a custom JsonConverter for your Item class and use that during serialization. A JsonConverter allows you to have complete control over what gets written during the serialization process for a particular class. You can add properties, suppress properties, or even write out a different structure if you want. For this particular situation, I think it is probably overkill, but it is another option.
Following is the cleanest way I could implement this
dynamic obj = JsonConvert.DeserializeObject(jsonstring);
obj.NewProperty = "value";
var payload = JsonConvert.SerializeObject(obj);
You could use ExpandoObject.
Deserialize to that, add your property, and serialize back.
Pseudocode:
Expando obj = JsonConvert.Deserializeobject<Expando>(jsonstring);
obj.AddeProp = "somevalue";
string addedPropString = JsonConvert.Serializeobject(obj);
I think the most efficient way to serialize a property that doesn't exist in the type is to use a custom contract resolver. This avoids littering your class with the property you don't want, and also avoids the performance hit of the extra serialization round trip that most of the other options on this page incur.
public class SpecialItemContractResolver : DefaultContractResolver {
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) {
var list = base.CreateProperties(type, memberSerialization);
if (type.Equals(typeof(Item))) {
var feeClassProperty = CreateFeeClassProperty();
list.Add(feeClassProperty);
}
return list;
}
private JsonProperty CreateFeeClassProperty() {
return new JsonProperty {
PropertyName = "feeClass",
PropertyType = typeof(string),
DeclaringType = typeof(Item),
ValueProvider = new FeeClassValueProvider(),
AttributeProvider = null,
Readable = true,
Writable = false,
ShouldSerialize = _ => true
};
}
private class FeeClassValueProvider : IValueProvider {
public object GetValue(object target) => "A";
public void SetValue(object target, object value) { }
}
}
To use this functionality:
// This could be put in a static readonly place so it's reused
var serializerSettings = new JsonSerializerSettings {
ContractResolver = new SpecialItemContractResolver()
};
// And then to serialize:
var item = new Item();
var json = JsonConvert.Serialize(item, serializerSettings);

Converting A plain old object to value object

I think Im having a really noob moment, Im returning a remote object from coldfusion and I want to specify the object type. i.e Im getting an worker from coldfusion and I have a Value object Worker.
Heres what I have been trying
public function ResultHandler_GetWorker(event:ResultEvent):void
{
var result:ArrayCollection = ArrayCollection(event.result);
var worker:WorkerVO = WorkerVO(result[0]);
model.worker = worker;
}
Result[0] is an employee object. Its structure from debug looks like this.
workerAddress "24b fake Ave"
workerCity "Wellton"
workerCountry "Ameriland"
workerEmail "Afake#me.com"
workerFName "Foo"
workerHPhone "435234"
workerID 1
workerImage null
workerIsAdmin true
workerLName "Foo"
workerMPhone "827271903"
workerPassword "password"
workerPosition "Leader"
workerState ""
workerSuburb "Birkenhead"
workerWPhone null
my class looks like this:
public class WorkerVO
{
public var _workerAddress:String
public var _workerCity:String
public var _workerCountry:String
public var _workerEmail:String
public var _workerFName:String
public var _workerHPhone:String
public var _workerID:uint;
public var _workerImage:String
public var _workerIsAdmin:Number;
public var _workerLName:String
public var _workerMPhone:String;
public var _workerPassword:String;
public var _workerPosition:String;
public var _workerState:String;
public var _workerSuburb:String;
public var _workerWPhone:String;
public function WorkerVO()
{
}
//Getters & Setters
}
Error #1034: Type Coercion failed: cannot convert Object#114eeb251 to com.cavej03.sitesafe.vo.WorkerVO.
Am I doing it completely wrong. Am I simply meant to make a function or constructor that accepts this object and maps its fields to a new WorkerVO
You're missing a RemoteClass metadata tag. This tag tells your application which server-side VO a given client-side VO is mapped to.
Use it like this:
[RemoteClass(alias="path.to.WorkerVO")] //this is the servers-side path
public class WorkerVO {
...
}
Furthermore from what you're showing it looks like the names of your properties don't match: the client-side one has prepended underscores while the server-side one doesn't.
The property names of the client-side VO and the server-side one should be exactly the same. For instance:
/* Java VO */
public class WorkerVO {
private String workerAddress;
public String getWorkerAddress() {
return workerAddress;
}
public void setWorkerAddress(String workerAddress) {
this.workerAddress = workerAddress;
}
}
/* ActionScript VO */
[RemoteClass(alias="path.to.WorkerVO")]
public class WorkerVO {
public var workerAddress:String;
}
This is an example with a Java VO, but the same applies to ColdFusion.
Assign the returned object to a property within WorkerVO, and prepare getters for each of them like so:
public class WorkerVO
{
private var _base:Object;
public function WorkerVO(base:Object)
{
_base = base;
}
public function get address():String{ return _base.workerAddress; }
public function get city():String{ return _base.workerCity; }
// Etc.
}
And the definition of a worker just needs the new keyword added:
var worker:WorkerVO = new WorkerVO(result[0]);
trace(worker.address);

ActionScript - Determine If Value is Class Constant

i'd like to throw an argument error if a particular function doesn't work without a passed value that also happens to be a public constant of the class containing the function.
is there anyway to determine if a class owns a public constant instead of having to iterate thru all of them?
something like this:
public static const HALIFAX:String = "halifax";
public static const MONTREAL:String = "montreal";
public static const TORONTO:String = "toronto";
private var cityProperty:String;
public function set city(value:String):void
{
if (!this.hasConstant(value))
throw new ArgumentError("set city value is not applicable.");
cityProperty = value;
}
public function get city():Strig
{
return cityProperty;
}
currently, for this functionality i have to write the city setter function like this:
public function set city(value:String):void
{
if (value != HALIFAX && value != MONTREAL && value != TORONTO)
throw new ArgumentError("set city value is not applicable.");
cityProperty = value;
}
is this the only way to accomplish this task?
Yes, if you use reflections:
private var type:Class;
private var description:XML;
private function hasConstant (str : String ) : Boolean
{
if (description == null)
{
type = getDefinitionByName (getQualifiedClassName (this)) as Class;
description = describeType (type);
}
for each ( var constant:XML in description.constant)
{
if (type[constant.#name] == str) return true;
}
return false;
}
Note that for this to work, all constants must always be String objects declared public static const.
I was looking for an answer to this question myself and found it annoying that hasOwnProperty() did not work for static properties. Turns out though, that if you cast your class to a Class object, it does work.
Here's an example:
public final class DisplayMode
{
public static const one: String = "one";
public static const two: String = "two";
public static const three: String = "three";
public static function isValid(aDisplayMode: String): Boolean {
return Class(DisplayMode).hasOwnProperty(aDisplayMode);
}
}
I owe this solution to jimmy5804 from this discussion, so hats off to him.
You should be able to use bracket notation to do this. For example:
var foo:Sprite = new Sprite();
foo.rotation = 20;
trace( foo["x"], foo["rotation"]); // traces "0 20"
or more specific to your case:
var bar:String = "rotation";
trace( foo[bar] ); // traces "20"
The only thing you have to look out for here, is that the bracket accessor will throw a ReferenceError if you ask for an object property that isn't there, such as:
trace ( foo["cat"] ); // throws ReferenceError
But it will not throw if you are asking for a static property:
trace ( Sprite["cat"] ); // traces "undefined"
So in your case you might try:
if ( this[value] == undefined ) {
throw new ArgumentError("set city value is not applicable.");
}
EDIT:
Sorry, I was confusing the const's names with their values.
For this to work on your problem you would have to make the String value the same as the const's name, so for example:
public static const HALIFAX:String = "HALIFAX";
then you could use the query as described above and it would give you the desired result.